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



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


  • administrators

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



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



  • 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

  • administrators

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



  • Thank you for that, removed it!


Log in to reply
 

});