Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Creating of my own strategy based on mean reversion

    General Discussion
    3
    6
    96
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Jana Stará
      Jana Stará last edited by

      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(self.data, period = self.params.period)
          self.std = bt.indicators.StandardDeviation(self.data, period = self.params.period)
          self.zscore = (self.dataclose - self.sma) / self.std (self.data)
      

      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
                  else:
                      return self.state[-1]
              else:
                  return 0  
              
          def signal(self):
              if self.state[0] == self.state[-1]:
                  return 0
              else:
                  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]:
              return
          
          # Check if an order has been completed (broker could reject order if not enough cash)
          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):
          # 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:
              return
          
          # 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 = self.buy()
              
              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()
      run-out 1 Reply Last reply Reply Quote 0
      • run-out
        run-out @Jana Stará last edited by

        @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:

        self.signal()
        self.state()
        
        1 Reply Last reply Reply Quote 0
        • R
          rajanprabu last edited by

          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.

          Jana Stará 1 Reply Last reply Reply Quote 0
          • Jana Stará
            Jana Stará @rajanprabu last edited by

            @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?

            1 Reply Last reply Reply Quote 0
            • R
              rajanprabu last edited by

              @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().

              1 Reply Last reply Reply Quote 0
              • run-out
                run-out last edited by

                This is a reasonably complicated indicator for a beginner. You should create a custom indicator.

                Look here for further help:
                https://www.backtrader.com/blog/posts/2015-07-18-developing-an-indicator/developing-an-indicator/

                https://medium.com/@danjrod/custom-indicator-development-in-python-with-backtrader-bc775552dc3e

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
                $(document).ready(function () { app.coldLoad(); }); }