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/

    Multiple Data Feeds (Instruments) on a single strategy

    Indicators/Strategies/Analyzers
    4
    5
    4261
    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.
    • S
      satheesh7134 last edited by

      Hi All

      I am new to Back trader and I am in need of your help to test my strategy on multiple instrument data.
      I have pasted the code below, I am expecting the strategy to run for both the data feeds, but actually its running for only one data feed. Please let me know what I should be changing to make it run for both the instrument data feeds. Thanks in advance

      -- Satheesh Kumar

      from future import (absolute_import, division, print_function,
      unicode_literals)

      import argparse
      import backtrader as bt
      import backtrader.feeds as btfeeds
      import datetime as dt
      import pandas as p

      class TestStrategy(bt.Strategy):
      params = (
      ('smaPeriod', 10),
      )

      def __init__(self):
          
          #Retrieves Close price data from the object
          self.dataclose = self.data.close
          
          #To keep track of pending orders and buy price / commission.
          self.order = None
          self.buyprice = None
          self.commission = None
          
          #SMA Indicator
          self.sma = bt.indicators.MovingAverageSimple(self.data, period=self.params.smaPeriod)
      
          # Indicators for the plotting show
          bt.indicators.ExponentialMovingAverage(self.data, period=25)
          bt.indicators.WeightedMovingAverage(self.data, period=25).subplot = True
          bt.indicators.StochasticSlow(self.data)
          bt.indicators.MACDHisto(self.data)
          rsi = bt.indicators.RSI(self.data)
          bt.indicators.SmoothedMovingAverage(rsi, period=10)
          bt.indicators.ATR(self.data).plot = False
          
          
      def notify_order(self, order):
      
          #Check whether an order is Submitted or Accepted by the Broker
          if order.status in [order.Submitted, order.Accepted]:
              return
      
          #Check if an order is completed
          if order.status in [order.Completed]:
              if order.isbuy():
      
                  print('Buy Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % 
                        (order.executed.price,
                         order.executed.value,
                         order.executed.comm
                        ))
      
                  self.buyprice = order.executed.price
                  self.commission = order.executed.comm
      
      
              elif order.issell():
                  print('Sell Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % 
                        (order.executed.price,
                         order.executed.value, #for sell this is not working as expected
                         order.executed.comm
                        ))
      
              self.bar_executed = len(self)
      
          elif order.status in [order.Canceled, order.Margin, order.Rejected]:
              print('Order Canceled/Margin/Rejected')
              
          
          self.order = None
          
      def notify_trade(self, trade):
              if not trade.isclosed:
                  return
      
              print('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                   (trade.pnl, trade.pnlcomm))
      
          
      def next(self): 
         
          print('Date, %s, Close, %.2f' % (self.data.datetime.date(0), self.dataclose[0]))
      
          #Check if an order is in Pending state, if yes, we cannot send a 2nd one
          if self.order:
      
              print('An order already in Pending state')
              return
      
          #Check whether we have an open position already, if no, then we can enter a new position by entering a BUY trade
          if not self.position:
      
              if self.dataclose[0] > self.sma[0]:
                  print('BUY Signal:, %.2f' % self.dataclose[0])
                  self.order = self.buy()
        
          #if there is an existing position already, then we have to close it after 5 consecutive bars 
          else:
              if self.dataclose[0] < self.sma[0]:
                  print('Sell Signal:, %.2f' % self.dataclose[0])
                  self.order = self.sell() 
      

      if name == 'main':

      cerebro = bt.Cerebro() 
      cerebro.addstrategy(TestStrategy) #Adds the strategy
      
      orcl = p.read_csv('D:\Algoticks\Excercises\Data\orcl_price-history-05-21-2018.csv')
      orcl['datetime'] = orcl['datetime'].astype('datetime64[ns]')
      
      orcl_stg = bt.feeds.PandasData(dataname = orcl)
      
      hcl = p.read_csv('D:\Algoticks\Excercises\Data\hcl_price-history-05-21-2018.csv')
      hcl['datetime'] = hcl['datetime'].astype('datetime64[ns]')
      
      hcl_stg = bt.feeds.PandasData(dataname = hcl)
      
      cerebro.adddata(orcl_stg)   #Adds the data for the strategy
      cerebro.adddata(hcl_stg)
      
      #set the cash
      cerebro.broker.setcash(100000.0)
      #set broker commission
      cerebro.broker.setcommission(commission = 0.001) #.1 percentage
      #set the quantity
      cerebro.addsizer(bt.sizers.FixedSize, stake = 10)
      
      #cerebro.addwriter(bt.WriterFile, csv=True)
      
      print('Starting Portfolio Value : %.2f' % cerebro.broker.getvalue())
      cerebro.run()
      #data.head()
      print('Final Portfolio Value : %.2f' % cerebro.broker.getvalue())
      
      1 Reply Last reply Reply Quote 0
      • S
        satheesh7134 last edited by

        Hi All

        Please ignore the previous code and please look at this code block. Sorry for the mistake

        from future import (absolute_import, division, print_function,
        unicode_literals)

        import argparse

        import backtrader as bt
        import backtrader.feeds as btfeeds
        import datetime as dt

        import pandas as p

        class TestStrategy(bt.Strategy):
        params = (
        ('smaPeriod', 10),
        )

        def __init__(self):
            
            #Retrieves Close price data from the object
            #self.dataclose = self.data.close
            
            #To keep track of pending orders and buy price / commission.
            self.order = None
            self.buyprice = None
            self.commission = None
            
        
            
        def notify_order(self, order):
        
            #Check whether an order is Submitted or Accepted by the Broker
            if order.status in [order.Submitted, order.Accepted]:
                return
        
            #Check if an order is completed
            if order.status in [order.Completed]:
                if order.isbuy():
        
                    print('Buy Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % 
                          (order.executed.price,
                           order.executed.value,
                           order.executed.comm
                          ))
        
                    self.buyprice = order.executed.price
                    self.commission = order.executed.comm
        
        
                elif order.issell():
                    print('Sell Executed Price: %.2f, Cost : %.2f, Commission : %.2f' % 
                          (order.executed.price,
                           order.executed.value, #for sell this is not working as expected
                           order.executed.comm
                          ))
        
                self.bar_executed = len(self)
        
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                print('Order Canceled/Margin/Rejected')
                
            
            self.order = None
            
        def notify_trade(self, trade):
                if not trade.isclosed:
                    return
        
                print('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                     (trade.pnl, trade.pnlcomm))
        
            
        def next(self): 
           
            
        
            for datafeed in self.getdatanames():
                print('Date, %s, Close, %.2f' % (self.getdatabyname(datafeed).datetime.date(0), self.getdatabyname(datafeed).close[0]))
                #Check if an order is in Pending state, if yes, we cannot send a 2nd one
                if self.order:
        
                    print('An order already in Pending state')
                    return
        
            #Check whether we have an open position already, if no, then we can enter a new position by entering a BUY trade
                if not self.position:
        
                    if self.getdatabyname(datafeed).close[0] < self.getdatabyname(datafeed).close[-1]:
        
                        if self.getdatabyname(datafeed).close[-1] < self.getdatabyname(datafeed).close[-2]:
                            
                            print('BUY Signal:, %.2f' % self.getdatabyname(datafeed).close[0])
                            self.order = self.buy()
                
                elif self.position:
        
                     if len(self) >= (self.bar_executed + 4):
        
                        print('Sell Signal:, %.2f' % self.getdatabyname(datafeed).close[0])
                        self.order = self.sell()
        

        if name == 'main':

        cerebro = bt.Cerebro() 
        cerebro.addstrategy(TestStrategy) #Adds the strategy
        
        orcl = p.read_csv('D:\Algoticks\Excercises\Data\orcl_price-history-05-21-2018.csv')
        orcl['datetime'] = orcl['datetime'].astype('datetime64[ns]')
        
        orcl_stg = bt.feeds.PandasData(dataname = orcl)
        
        hcl = p.read_csv('D:\Algoticks\Excercises\Data\hcl_price-history-05-21-2018.csv')
        hcl['datetime'] = hcl['datetime'].astype('datetime64[ns]')
        
        hcl_stg = bt.feeds.PandasData(dataname = hcl)
        
        cerebro.adddata(orcl_stg)   #Adds the data for the strategy
        cerebro.adddata(hcl_stg)    
        
        #set the cash
        cerebro.broker.setcash(100000.0)
        #set broker commission
        cerebro.broker.setcommission(commission = 0.001) #.1 percentage
        #set the quantity
        cerebro.addsizer(bt.sizers.FixedSize, stake = 10)
        
        #cerebro.addwriter(bt.WriterFile, csv=True)
        
        print('Starting Portfolio Value : %.2f' % cerebro.broker.getvalue())
        cerebro.run()
        #data.head()
        print('Final Portfolio Value : %.2f' % cerebro.broker.getvalue())
        
        D B 2 Replies Last reply Reply Quote 0
        • D
          Divyanshu Bagga @satheesh7134 last edited by

          @satheesh7134 Go through the multi data feeds example.

          You need to use enumerate(self.datas) to evaluate strategy on each data feed separately.

          P 1 Reply Last reply Reply Quote 0
          • P
            param.jeet @Divyanshu Bagga last edited by

            @divyanshu-bagga :
            In that case, wouldn't cerebro.run( ) execute twice? If I run twice then I would get two different datasets.

            What if, I want to execute this strategy on both data sets and generate single report as one single portfolio.

            1 Reply Last reply Reply Quote 0
            • B
              backtrader administrators @satheesh7134 last edited by

              @satheesh7134 said in Multiple Data Feeds (Instruments) on a single strategy:

                                  print('BUY Signal:, %.2f' % self.getdatabyname(datafeed).close[0])
                                  self.order = self.buy()
              

              He wasn't telling the system what to buy (or sell). See Docs - Strategy and the reference for buy / sell

              or as pointed out by @Divyanshu-Bagga

              @divyanshu-bagga said in Multiple Data Feeds (Instruments) on a single strategy:

              @satheesh7134 Go through the multi data feeds example.

              @param-jeet said in Multiple Data Feeds (Instruments) on a single strategy:

              In that case, wouldn't cerebro.run( ) execute twice? If I run twice then I would get two different datasets.
              What if, I want to execute this strategy on both data sets and generate single report as one single portfolio.

              You enumerate within the strategy.

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