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

Creating of my own strategy based on mean reversion

  • Hi,

    I try to create my own strategy which is based on mean reversion strategy. The code passed in Backtrader but it didn't give me a desired output. Could you please write me, what I am doing wrong?

    I am still a beginner, but hope there won't be plenty of mistakes and any suggestion will be greatly appreciated. :-)

      def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close
        # To keep track of pending orders and buy price/commission
        self.order = None
        self.buyprice = None
        self.buycomm = None
        # Add Indicators
        self.sma = bt.indicators.SimpleMovingAverage(, period = self.params.period)
        self.std = bt.indicators.StandardDeviation(, period = self.params.period)
        self.zscore = (self.dataclose - self.sma) / self.std (

    Defining new variables state and signal:

        def state(self):
            if np.sign(self.zscore[0]) == np.sign(self.zscore[-1]):
                if self.zscore[0] > 1:
                    return 1
                elif self.zscore[0] < -1:
                    return -1
                    return self.state[-1]
                return 0  
        def signal(self):
            if self.state[0] == self.state[-1]:
                return 0
                return self.state[0] - self.state[-1]

    then the own strategy:

    def notify_order(self, order):
        # Buy/Sell order submitted/accepted by broker (nothing to do)
        if order.status in [order.Submitted, order.Accepted]:
        # Check if an order has been completed (broker could reject order if not enough cash)
        if order.status in [order.Completed]:
            if order.isbuy():
                    'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                self.buyprice = order.executed.price
                self.buycomm = order.executed.comm
            else:  # Sell
                self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
            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:
        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm))
    def next(self):
        # log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])
        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
        # Check if we are in the market
        if not self.position:
            # Not in the market, we might buy...
            if self.signal[0] == -1:
                # BUY! (with all possible default parameters)
                self.log('BUY CREATED {}'.format(self.dataclose[0]))
                # Keep track of the created order to avoid a 2nd order
                self.order =
            elif self.signal[0] == 1:
                self.log('SELL CREATE, %.2f' % self.dataclose[0])
                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

  • @Jana-Stará said in Creating of my own strategy based on mean reversion:

    if self.signal[0] == -1:

    I could be wrong but I think you need to call self.signal and self.state with rounded brackets:


  • IN addition to that @run-out has pointed out. self.zscore is the line object, but self.state is not. if you need self.state[-1] then either make self.state a line object or make a variable self.prev_state and update for every step.

  • @rajanprabu Thank you for your help. I got your point but I don't know exactly how to do it. Could you please write me some hint, how to make a self.state a line object?

  • @Jana-Stará

    As for as I understand, you only need two values self.signal[0] and self.signal[-1]. So making it as a line object may not be optimal. Just initialise two variables under init say self.prev_state, self.state and and update the values of self.prev_state during next().

Log in to reply