Backtrader Community

    • 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/

    unable to execute strategies on resampled data

    General Code/Help
    resampled data strategy plotting data feeds
    3
    8
    720
    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.
    • Nikhil Kumar
      Nikhil Kumar last edited by

      Hi Traders ,
      I needed assistance with an issue i was facing.

      Here is my code :

      # This is the Implementation for 9/30 Stratergy using python BackTrader 
      import backtrader as bt
      from datetime import datetime
      import datetime as dt
      import pandas as pd
      import matplotlib.pyplot as plt
      from pandas_datareader import data as web
      
      class PullBack(bt.Strategy):
      
      
          def log(self, txt, dt=None):
              #  Logging function fot this strategy
              dt = dt or self.datas[0].datetime.date(0)
              print('%s, %s' % (dt.isoformat(), txt))
      
          def __init__(self):
              self.open = self.data.open
              self.high = self.data.high
              self.low = self.data.low
              self.close = self.data.close
      
              self.ema = bt.ind.ExponentialMovingAverage(self.data.close, period=9)
              self.wma = bt.ind.WeightedMovingAverage(self.data.close, period=30)
      
              self.order = None
              self.stop_order = None
      
          def next(self):
             #print("current portfolio value" + str(cerebro.broker.getvalue()))
              
              
              if not self.position:
                  # Long Position
                  if (self.ema[-1] > self.wma[-1]) and (self.data.high[-1] < self.ema[-1]) :
                      self.buy(size=100, exectype=bt.Order.StopLimit, price=self.data.high[-1])
                      self.order = self.buy(size=1, exectype=bt.Order.Limit, price=self.data.high[-1])
                      self.log('BUY PRICE CREATED , %.2f ' % self.data.high[-1])
                      risk = (self.data.high[-1] - self.data.low[-1])
                      self.log('Risk points , %.2f' % risk)
                      # Place a stop loss order
                      self.sell(size=100, exectype=bt.Order.StopLimit, price=self.data.low[-1])
                      target_price = self.data.high[-1] + 2 * (self.data.high[-1] - self.data.low[-1])
                      self.log('TARGET PRICE ,%.2f ' % target_price)
                      oc1 = self.sell(size=1, exectype=bt.Order.StopLimit, price=target_price)
                      self.order = self.sell(size=1, exectype=bt.Order.Stop, price=self.data.low[-1], plimit=self.data.low[-1] , oco=oc1)
                  # elif (self.ema[-1] < self.wma[-1]) and  (self.data.close[-1] > self.ema[-1] )  :
                      
                  #     self.order = self.sell(size=1,exectype=bt.Order.Limit,price=self.data.low[-1])
                  #     #Stop loss
                  #     target_price = self.data.low[-1] - 2 * (self.data.high[-1] - self.data.low[-1])
                  #     self.order = self.sell(size=1,exectype=bt.Order.StopLimit,price=target_price)
                  #     self.log('Short Sell initiated , %.2f' % self.data.low[-1])
                      
      
      
      
          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, %.2f' % order.executed.price)
                  elif order.issell():
                      self.log('Sell order EXECUTED, %.2f' % order.executed.price)
      
              elif order.status in [order.Cancelled]:
                  self.log('Order Canceled at price, %.2f' %order.price)
      
              elif order.status in [ order.Margin, order.Rejected]:
                  self.log('Order Rejected or Margin error')
      
              self.order = None
      
      class timeAdjustment(bt.TradingCalendar):
              params = dict(
              holidays=[
                  dt.date(2018, 1, 26),
                  # dt.date(2018, 2, 13),
                  # dt.date(2018, 3, 2),
                  # dt.date(2018, 3, 29),
                  # dt.date(2018, 3, 30),
                  # dt.date(2018, 5, 1),
                  # dt.date(2018, 8, 15),
                  # dt.date(2018, 8, 22),
                  # dt.date(2018, 9, 13),
                  # dt.date(2018, 9, 18),
                  # dt.date(2018,10,2),
                  # dt.date(2018,10,18),
                  # dt.date(2018,11,8),
                  # dt.date(2018,11,23),
                  # dt.date(2018,12,2)
              ],
              # earlydays=[
              #     (dt.date(2018, 11, 7),
              #      dt.time(17, 31), dt.time(18, 31))
              # ],
              open=dt.time(9, 16),
              close=dt.time(15, 30),
          
          )
      
      
      
      
      #Variable for our starting cash
      startcash = 100000
      
      #Create an instance of cerebro
      cerebro = bt.Cerebro()
      
      #Add our strategy
      cerebro.addstrategy(PullBack)
      
      nifty_futures="C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\BackTestFiles\\input_data\\BANKNIFTY-IBKR (1).csv"
      # nifty_futures = 'C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\2018data.csv'
      
      
      data = bt.feeds.GenericCSVData(
          headers=True,
          dataname=nifty_futures,
          # 2020-03-13
          fromdate=datetime(2018, 1, 1),    #year-month-date
          todate=datetime(2018, 1, 31),
          nullvalue=0.0,
          dtformat=("%Y-%m-%d %H:%M:%S"),
          # tmformat=('%H:%M:%S'),
          datetime=1,
          # time=3,
          open=2,
          high=3,
          low=4,
          close=5,
          timeframe=bt.TimeFrame.Minutes,
          plot=False
      
      )
      
      
      cerebro.adddata(data)
      cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=30,name='30_Min_data')
      # cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=60,name='60_min_bar')
      # cerebro.addcalendar(timeAdjustment)
      
      # Set our desired cash start
      cerebro.broker.setcash(startcash)
      
      
      # Add the analyzers we are interested in
      cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta")
      cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn")
      cerebro.broker.setcommission(commission=0.0005)
      
      
      # Run over everything
      strategies=cerebro.run()
      
      #Get final portfolio Value
      
      portvalue = cerebro.broker.getvalue()
      print("final and last port value:  "+str(portvalue))
      pnl = portvalue - startcash
      
      #Print out the final result
      
      print('Final Portfolio Value: ${}'.format(portvalue))
      print('P/L: ${}'.format(pnl))
      
      #Finally plot the end results
      
      cerebro.plot(style='candlestick',fmt_x_data = ('%Y-%m-%d %H:%M:%S'))
      
       
      

      Ideally I want my strategy to run on resampled data , but in the end what i get is the below plot .

      (Figure_0.png

      As you can see no Buy sell indiactors have been displayed.
      May i know why this happening ??

      I also tried commenting
      cerebro.add(data)

      But this change gives me an empty plot .

      Thanks

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

        You need to use resampled data in your strategy which is data1, but you are referencing the data aka data0 which is the input data.

        1 Reply Last reply Reply Quote 1
        • Nikhil Kumar
          Nikhil Kumar last edited by

          Thanks for the input rajan

          1 Reply Last reply Reply Quote 0
          • Nikhil Kumar
            Nikhil Kumar last edited by

            I made the changes you mentioned ie reference data by data[1]
            . I tried using data1 but it gave me an error saying it was undefined.
            However after using data[1] I got this error

              File "c:\Nikhil_Media\Education & Skills\Stratergies_Codes\BackTestFiles\Resampled_930Stratergy.py", line 18, in __init__
                self.open = self.data[1].open
            AttributeError: 'float' object has no attribute 'open'
            

            Below is the modified code
            Appreciate your assistance

            # This is the Implementation for 9/30 Stratergy using python BackTrader 
            import backtrader as bt
            from datetime import datetime
            import datetime as dt
            import pandas as pd
            import matplotlib.pyplot as plt
            from pandas_datareader import data as web
            
            class PullBack(bt.Strategy):
            
            
                def log(self, txt, dt=None):
                    #  Logging function fot this strategy
                    dt = dt or self.datas[0].datetime.date(0)
                    print('%s, %s' % (dt.isoformat(), txt))
            
                def __init__(self):
                    self.open = self.data[1].open
                    self.high = self.data[1].high
                    self.low = self.data[1].low
                    self.close = self.data[1].close
            
                    self.ema = bt.ind.ExponentialMovingAverage(self.data[1].close, period=9)
                    self.wma = bt.ind.WeightedMovingAverage(self.data[1].close, period=30)
            
                    self.order = None
                    self.stop_order = None
            
                def next(self):
                   #print("current portfolio value" + str(cerebro.broker.getvalue()))
                    
                    
                    if not self.position:
                        # Long Position
                        if (self.ema[-1] > self.wma[-1]) and (self.data[1].close[-1] < self.ema[-1]) :
                            print('close price : {}, ema : {}'.format(self.data[1].close[-1],self.ema[-1]))
                            print('current close price {}'.format(self.data[1].high[0]))
                            # self.buy(size=100, exectype=bt.Order.StopLimit, price=self.data.high[-1])
                            self.order = self.buy(size=1, exectype=bt.Order.Limit, price=self.data[1].high[-1])
                            self.log('BUY PRICE CREATED , %.2f ' % self.data[1].high[-1])
                            risk = (self.data[1].high[-1] - self.data[1].low[-1])
                            self.log('Risk points , %.2f' % risk)
                            # Place a stop loss order
                            # self.sell(size=100, exectype=bt.Order.StopLimit, price=self.data.low[-1])
                            target_price = self.data[1].high[-1] + 2 * (self.data[1].high[-1] - self.data[1].low[-1])
                            self.log('TARGET PRICE ,%.2f ' % target_price)
                            oc1 = self.sell(size=1, exectype=bt.Order.StopLimit, price=target_price)
                            self.order = self.sell(size=1, exectype=bt.Order.Stop, price=self.data[1].low[-1], plimit=self.data[1].low[-1] , oco=oc1)
            
                        # elif (self.ema[-1] < self.wma[-1]) and  (self.data.close[-1] > self.ema[-1] )  :
                            
                        #     self.order = self.sell(size=1,exectype=bt.Order.Limit,price=self.data.low[-1])
                        #     #Stop loss
                        #     target_price = self.data.low[-1] - 2 * (self.data.high[-1] - self.data.low[-1])
                        #     self.order = self.buy(size=1,exectype=bt.Order.StopLimit,price=target_price)
                        #     self.log('Short Sell initiated , %.2f' % self.data.low[-1])
            
                            
            
            
            
                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, %.2f' % order.executed.price)
                        elif order.issell():
                            self.log('Sell order EXECUTED, %.2f' % order.executed.price)
            
                    elif order.status in [order.Cancelled]:
                        self.log('Order Canceled at price, %.2f' %order.price)
            
                    elif order.status in [ order.Margin, order.Rejected]:
                        self.log('Order Rejected or Margin error')
            
                    self.order = None
            
            class timeAdjustment(bt.TradingCalendar):
                    params = dict(
                    holidays=[
                        dt.date(2018, 1, 26),
                        # dt.date(2018, 2, 13),
                        # dt.date(2018, 3, 2),
                        # dt.date(2018, 3, 29),
                        # dt.date(2018, 3, 30),
                        # dt.date(2018, 5, 1),
                        # dt.date(2018, 8, 15),
                        # dt.date(2018, 8, 22),
                        # dt.date(2018, 9, 13),
                        # dt.date(2018, 9, 18),
                        # dt.date(2018,10,2),
                        # dt.date(2018,10,18),
                        # dt.date(2018,11,8),
                        # dt.date(2018,11,23),
                        # dt.date(2018,12,2)
                    ],
                    # earlydays=[
                    #     (dt.date(2018, 11, 7),
                    #      dt.time(17, 31), dt.time(18, 31))
                    # ],
                    open=dt.time(9, 16),
                    close=dt.time(15, 30),
                
                )
            
            
            
            
            #Variable for our starting cash
            startcash = 100000
            
            #Create an instance of cerebro
            cerebro = bt.Cerebro()
            
            #Add our strategy
            cerebro.addstrategy(PullBack)
            
            nifty_futures="C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\BackTestFiles\\input_data\\BankNifty30min.csv"
            # nifty_futures = 'C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\2018data.csv'
            
            # Note : For custom created csv's ( like resampled ones ) always mention which columns are not present in the 
            #  data feed
            data = bt.feeds.GenericCSVData(
                headers=True,
                dataname=nifty_futures,
                # 2020-03-13
                fromdate=datetime(2019, 1, 1),    #year-month-date
                todate=datetime(2019, 1, 31),
                nullvalue=0.0,
                dtformat=("%Y-%m-%d %H:%M:%S"),
                # tmformat=('%H:%M:%S'),
                datetime=0,
                # time=3,
                open=1,
                high=2,
                low=3,
                close=4,
                volume = -1,
                openinterest = -1,
                timeframe=bt.TimeFrame.Minutes,
                # plot=False
            
            )
            
            
            cerebro.adddata(data)
            # cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=30,name='30_Min_data')
            # cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=60,name='60_min_bar')
            # cerebro.addcalendar(timeAdjustment)
            
            # Set our desired cash start
            cerebro.broker.setcash(startcash)
            
            
            # Add the analyzers we are interested in
            cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta")
            cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn")
            cerebro.broker.setcommission(commission=0.0005)
            
            
            # Run over everything
            strategies=cerebro.run()
            
            #Get final portfolio Value
            
            portvalue = cerebro.broker.getvalue()
            print("final and last port value:  "+str(portvalue))
            pnl = portvalue - startcash
            
            #Print out the final result
            
            print('Final Portfolio Value: ${}'.format(portvalue))
            print('P/L: ${}'.format(pnl))
            
            #Finally plot the end results
            
            cerebro.plot(style='candlestick',fmt_x_data = ('%Y-%m-%d %H:%M:%S'))
            
             
            
            R 1 Reply Last reply Reply Quote 0
            • R
              rajanprabu @Nikhil Kumar last edited by

              @Nikhil-Kumar
              you should first read Platform concepts and handling MultiTimeframe in backtrader. It will save lots of time for you. That would have clarified that datas[0] is not data0. You need to use data1 rather than data[1].

              A 1 Reply Last reply Reply Quote 0
              • A
                ab_trader @rajanprabu last edited by

                @rajanprabu said in unable to execute strategies on resampled data:

                That would have clarified that datas[0] is not data0. You need to use data1 rather than data[1].

                self.data0 is a shortcut for self.datas[0] as well as self.data1 is a shortcut for self.datas[1].

                @Nikhil-Kumar said in unable to execute strategies on resampled data:

                I made the changes you mentioned ie reference data by data[1]

                you commented out resampling of the data, therefore the script has no data1.

                • If my answer helped, hit reputation up arrow at lower right corner of the post.
                • Python Debugging With Pdb
                • New to python and bt - check this out
                R 1 Reply Last reply Reply Quote 1
                • R
                  rajanprabu @ab_trader last edited by

                  @ab_trader Thank you.. perhaps its me who has to read the docs again.

                  1 Reply Last reply Reply Quote 0
                  • Nikhil Kumar
                    Nikhil Kumar last edited by

                    Thanks @rajanprabu and @ab_trader for your assistance and knowledge .

                    Appreciate it

                    1 Reply Last reply Reply Quote 0
                    • 1 / 1
                    • First post
                      Last post
                    Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors