Extending Datafeeds GenericCSV Attribute Error



  • I have looked at extending the GenericCSV and am trying to add an additional column (pe) like in the example and am getting the error

    AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'pe'

    Hopefully i am doing something stupid but cannot seem to figure out why the GenericCSVpe isn't adding the pe parameter to the class?

    Here is my complete test code.

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import backtrader as bt
    import pandas as pd
    from backtrader.feeds import GenericCSVData
    import backtrader.feeds as btfeeds
    import datetime as datetime
    import backtrader.indicators as btind
    import numpy as np
    
    from backtrader.feeds import GenericCSVData
    
    class GenericCSV_PE(GenericCSVData):
    
        # Add a 'pe' line to the inherited ones from the base class
        lines = ('pe',)
    
        # openinterest in GenericCSVData has index 7 ... add 1
        # add the parameter to the parameters inherited from the base class
        params = (('pe', 8),)
    
    class MyStrategy(bt.Strategy):
    
    
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = self.datas[0].datetime.date(0)
            dt_time = self.datas[0].datetime.time(0)
            dt_weekday = datetime.datetime.weekday(dt)
            print('%s, %s' % (dt.isoformat(), txt))
    
    
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            # init stop loss and take profit order variables
            self.sl_order, self.tp_order = None, None
            self.datavolume = self.datas[0].volume
            self.pe = self.datas[0].pe
    
    
        def next(self):
            if self.datavolume[0] / np.mean(self.datavolume.get(size=10, ago=-1)) >= 1.25:
                self.buy()
                print(self.pe[0])
    
    
    
    if __name__ == '__main__':
        # Create a cerebro entity
        cerebro = bt.Cerebro()
    
    
        data = btfeeds.GenericCSVData(
            dataname='C:\\Users\\oso\\Dropbox\\All Devices\\Datav1.csv',
    
            nullvalue=0.0,
    
            dtformat=('%m/%d/%Y'),
    
            datetime=0,
            time=-1,
            high=2,
            low=3,
            open=1,
            close=4,
            volume=5,
            openinterest=6
        )
    
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
    
        # Set our desired cash start
        cerebro.broker.setcash(100000.0)
    
        # Add a strategy
        cerebro.addstrategy(MyStrategy)
    
        # Print out the starting conditions
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
        # Run over everything
        cerebro.run()
    
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
        cerebro.plot(style='bar')
    

    0_1507400960917_pe backtrader.PNG


  • administrators

    @Osofuego said in Extending Datafeeds GenericCSV Attribute Error:

    data = btfeeds.GenericCSVData(

    You are not using your own extended data feed.



  • @Osofuego said in Extending Datafeeds GenericCSV Attribute Error:

    dt = self.datas[0].datetime.date(0)

    Hello @Osofuego

    Hope all is well. I have a code structure remarkably similar to yours, and from what I see using the same syntax for datetime identical to you too. However, when I run it, I keep getting an error:

    ValueError: time data '"2014-12-31' does not match format '%m/%d/%Y'

    Wondering if you can quickly take a look at my code and see why mine is not running? A snapshot of the csv file format I am trying to import is shown below:

    0_1507742935812_Capture.PNG

    And my code is as following: (weird, it doesnt even show import datetime as datetime being imported at the top to beused, which could be part of the issue?)

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    
    import os.path  # To manage paths
    import sys  # To find out the script name (in argv[0])
    
    # Import the backtrader platform
    import backtrader as bt
    import backtrader.feeds as btfeeds
    import datetime as datetime
    
    
    # Create a Stratey
    class TestStrategy(bt.Strategy):
    
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def __init__(self):                              # upon __init__ being called the strategy already has a list of datas that are present in the platform. This is a standard Python list and datas can be accessed in the order they were inserted.
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close        # self.dataclose = self.datas[0].close keeps a reference to the close line. (close price)
                                                        # the first data in the list self.datas[0] is the default data for trading operations and to keep all strategy elements synchronized (its the system clock)
    
        def next(self):                                 # 'next' method will be called on each bar of the system clock (self.datas[0]). This is true until other things come into play like indicators, which need some bars to start producing an output.
            # Simply log the closing price of the series from the reference
            self.log('Close, %.2f' % self.dataclose[0])
    
            # if the price has been falling 3 sessions in a row..... buy buy buy!
            if self.dataclose[0] < self.dataclose[-1]:
                # current close less than previous close
    
                if self.dataclose[-1] < self.dataclose[-2]:
                    # previous close less than the previous close
    
                    # BUY, BUY, BUY!!! (with all possible default parameters)
                    self.log('BUY CREATE, %.2f' % self.dataclose[0])
                    self.buy()
    
    
    if __name__ == '__main__':
        # Create a cerebro entity
        cerebro = bt.Cerebro()
    
        # Add a strategy
        cerebro.addstrategy(TestStrategy)
    
        data = btfeeds.GenericCSVData(
            dataname='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.csv',
    
            #fromdate=datetime.datetime(2000/1/1),
            #todate = datetime.datetime(2000/12/31),
    
            nullvalue=0.0, # missing values to be replaced with 0
    
            dtformat=('%m/%d/%Y'),
    
            datetime=0,
            time=-1,
            open=1,
            high=2,
            low=3,
            close=4,
            adjclose=5,
            volume=6,
            openinterest=-1,
    
    
        )
    
    
    
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
    
        # Set our desired cash start
        cerebro.broker.setcash(100000.0)
    
        # Print out the starting conditions
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
        # Run over everything
        cerebro.run()
    
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    


  • I noticed the last line of my csv file had a formatted date that was an integer. I would check each line of your data first.



  • nevermind got it to work. Thanks!


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.