

Order Execution Price NAN - single column pandas data input

  • I am testing a very basic hello world script the exception being that I am using a single column pandas dataframe as my data source (because that is what I am using as the input for my strategy).

    Everything appears to be working fine, except that my the order object inside the loop shows price=nan and throws off the loop. When I check the value of the portfolio at the end of the script, it is nan. I'm assuming it is related to my data source but I cannot find the error looking through the source code.

        cerebro = bt.Cerebro()
        cerebro.addstrategy(EMACross, fast_period=11, slow_period=25)
        # Make data object - we only have a "close" in column 0
        data = bt.feeds.PandasData(dataname=btc_df, open=None, high=None, 
        low=None, close=0, volume=None, openinterest=None)
        cerebro.adddata(data) # add data to engine

    At this point, everything runs and prints to the console, the first order produces

    "> BUY EXECUTED, nan"

    Then, every order after produces a Rejected, Cancelled, Margin error.

    Here is my strategy object, you can see I am passing in size and price to the order function -

    class EMACross(bt.Strategy):
        def __init__(self, fast_period, slow_period):
            self.dataclose = self.datas[0].close
            self.order = None
            self.fastma = bt.ind.ExponentialMovingAverage(self.datas[0], period=fast_period)
            self.slowma  = bt.ind.ExponentialMovingAverage(self.datas[0], period=slow_period)
            self.buysig  = bt.ind.CrossOver(self.fastma, self.slowma)
            self.sellsig = bt.ind.CrossDown(self.fastma, self.slowma)
        def log(self, txt, dt=None):
            dt = dt or self.datas[0]
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
            if order.status in [order.Completed]:
                if order.isbuy():
                elif order.issell():
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Cancelled/Margin/Rejected')
            self.order = None
        def next(self):
            if self.order:
            # Initial Order
            if not self.position:
                if self.buysig > 0:
                    self.order =, price=self.dataclose[0])
                elif self.sellsig > 0:
                    self.order = self.sell(size=1, price=self.dataclose[0])
                else: return
            # Find out if we are long or short
            side = self.position.size
            if side > 0: # we are long
                if self.sellsig > 0:
                    self.order = self.sell(size=2, price=self.dataclose[0])
                if self.buysig > 0:
                    self.order =, price=self.dataclose[0])

    Any help is very much appreciated!! I've been debugging this for several hours. My first time using backtrader.

  • administrators

    See at the top


  • administrators

    See Docs - Order Execution and Management

    You want to see how Market orders are executed. This:

    @jmarks512 said in Order Execution Price NAN - single column pandas data input:

    self.order =, price=self.dataclose[0])

    is impossibility. You cannot specify the execution price of a Market order. Provide an opening price (you probably do also want to provide a high and low)

  • Makes perfect sense. I was able to get execution by specifying exectype=bt.Order.Close

    Thank you for the help!

  • administrators

    I think you are pretty new to trading and should take some time to understand things and grasp the concepts. Specifying exectype=bt.Order.Close has only done something which doesn't have the effect you are looking for.

    That order execution type is intended for intraday data, for orders which are issued before the trading day is over and which will be executed with the closing tick (in the most well known exchanges it does execute at the end of the auction which follows the end of regular trading)

    What you need:

    • Provide an open price (it can be the same as the close if you don't have any other) to get something realistic


    • Activatecheat-on-close and work with the current close (it is calledcheat for a reason)

Log in to reply