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 Bid/Ask pandas datafeed error

    General Code/Help
    3
    7
    1273
    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.
    • G
      gaya0007 last edited by

      Hi,

      I'm quite new to backtrader framework and trying to figure out how to create pandas bid/ask datafeed. Below is my data frame.
      print(df.head())

                      RateBid  RateAsk
      RateDateTime
      2018-12-03 00:00:00.340  1.13501  1.13503
      2018-12-03 00:00:00.590  1.13499  1.13503
      2018-12-03 00:00:00.857  1.13498  1.13502
      2018-12-03 00:00:01.107  1.13498  1.13503
      2018-12-03 00:00:01.340  1.13499  1.13503
      

      Implementation:

      import backtrader as bt
      import backtrader.feeds as btfeeds
      import backtrader.indicators as btind
      
      
      class BidAskDF(btfeeds.PandasData):
          linesoverride = True  # discard usual OHLC structure
          # datetime must be present and last
          lines = ('RateBid', 'RateAsk', 'datetime')
          # datetime (always 1st) and then the desired order for
          params = (
              #('datetime', 0), # inherited from parent class
              ('RateBid', 1),  # default field pos 1
              ('RateAsk', 2),  # default field pos 2
          )
          
      
      class St(bt.Strategy):
      
          def next(self):
              print('hello')
              #dtstr = self.data.datetime.datetime().isoformat()
              #txt = '%4d: %s - Bid %.4f - %.4f Ask' % (
              #	(len(self), dtstr, self.data.bid[0], self.data.ask[0]))
      
              #if self.p.sma:
              #	txt += ' - SMA: %.4f' % self.sma[0]
              #print(txt)
      
      cerebro = bt.Cerebro()
      data = BidAskDF(dataname = df, timeframe=bt.TimeFrame.Ticks, datetime='RateDateTime')
      
      cerebro.adddata(data)  # Add the 1st data to cerebro
      # Add the strategy to cerebro
      cerebro.addstrategy(St)
      cerebro.run()
      

      Im getting following error ,

      Exception in thread Thread-1:
      Traceback (most recent call last):
      File "C:\Users\admin\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 916, in _bootstrap_inner
      self.run()
      File "C:\Users\admin\AppData\Local\Programs\Python\Python36-32\lib\threading.py", line 864, in run
      self._target(*self._args, **self._kwargs)
      File "E:\Projects\Learning\Backtester\price_handler.py", line 59, in create_df
      self.ready_cb()
      File "E:\Projects\Learning\Backtester\gui.3.py", line 88, in cb_df_ready
      data = BidAskDF(dataname = df, timeframe=bt.TimeFrame.Ticks, datetime='RateDateTime')
      File "E:\Projects\Learning\Backtester\backtrader\metabase.py", line 88, in call
      _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
      File "E:\Projects\Learning\Backtester\backtrader\metabase.py", line 78, in doinit
      _obj.init(*args, **kwargs)
      File "E:\Projects\Learning\Backtester\backtrader\feeds\pandafeed.py", line 181, in init
      defmapping = getattr(self.params, datafield)
      AttributeError: 'AutoInfoClass_LineRoot_LineMultiple_LineSeries_Dat' object has no attribute

      could someone please point out what caused the error?

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

        @gaya0007 said in Creating Bid/Ask pandas datafeed error:

        AttributeError: 'AutoInfoClass_LineRoot_LineMultiple_LineSeries_Dat' object has no attribute
        

        Part of the error message is clearly missing.

        On the other hand, what you are trying to do was only done with the GenericCSVData feed. The implementation of PandasData may have problems as it heavily depends on the correspondence of the defined lines and the parameters and the parameters from the base class cannot be nullified.

        1 Reply Last reply Reply Quote 0
        • G
          gaya0007 last edited by

          @backtrader Thank you for that information. I will try to use the csv to create the datafeed instead of pandas df.

          1 Reply Last reply Reply Quote 0
          • G
            gaya0007 last edited by

            I've been reading the forum and I realised I could import the 'RateBid', 'RateAsk', 'RateDateTime' as seperate lines in the padas DF and use them. If someone is looking for similar method this might be useful.

            class PandasData_Extend(btfeeds.PandasData):
                lines = ('RateDateTime','RateBid','RateAsk')
            
                params = (
            	('datetime', None),
            	('RateDateTime', -1),
            	('RateBid', -1),
            	('RateAsk', -1)
                )
            
                btfeeds.PandasData.datafields = btfeeds.PandasData.datafields + [u'RateDateTime', u'RateBid', u'RateAsk']
            
            
            
            class Ticker(bt.Strategy):
                  def __init__(self):
            	self.tick_ength = 0
            	self.order = None
            	self.first_tick = True
            
            def notify_order(self, order):
            	if order.status in [order.Submitted, order.Accepted]:
            		# Buy/Sell order submitted/accepted to/by broker - Nothing to do
            		return
            
            	# Check if an order has been completed
            	# Attention: broker could reject order if not enough cash
            	if order.status in [order.Completed]:
            		if order.isbuy():
            			self.log('BUY EXECUTED, %.2f' % order.executed.price)
            		elif order.issell():
            			self.log('SELL EXECUTED, %.2f' % order.executed.price)
            
            		self.bar_executed = len(self)
            
            	elif order.status in [order.Canceled, order.Margin, order.Rejected]:
            		self.log('Order Canceled/Margin/Rejected')
            
            	# Write down: no pending order
            	self.order = None
            
                    def next(self):
            	    if self.tick_ength != len(self.datas[0]):
            		self.tick_ength = len(self.datas[0])
                                print(self.data.datetime.datetime(), self.data.RateBid[0], self.data.RateAsk[0])
            
            	tick_data = PandasData_Extend(dataname = tick_df)
            	self.cerebro.adddata(tick_data)  # Add the 1st data to cerebro
            
            B 1 Reply Last reply Reply Quote 0
            • B
              backtrader administrators @gaya0007 last edited by

              @gaya0007 said in Creating Bid/Ask pandas datafeed error:

                  btfeeds.PandasData.datafields = btfeeds.PandasData.datafields + [u'RateDateTime', u'RateBid', u'RateAsk']
              

              As pointed out many times before, this is no longer needed. Don't use it.

              The rest is simply the standard extension mechanism.

              asdasda 1 Reply Last reply Reply Quote 0
              • G
                gaya0007 last edited by

                Thank you for that, removed it!

                1 Reply Last reply Reply Quote 0
                • asdasda
                  asdasda @backtrader last edited by

                  @backtrader This is a common requirement. I don't understand why PandasData doesn't add a custom_ fields parameter to meet this feature.

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