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')
-
@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:
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!
-
Hi,
What was your mistake that you corrected. You just said you got it to work. I am getting the same error.
valueError: time data '"2016-12-31' does not match format '%m/%d/%Y'
thanks..
-
@samk said in Extending Datafeeds GenericCSV Attribute Error:
ValueError: time data '"2014-12-31' does not match format '%m/%d/%Y'
@michael172 said in Extending Datafeeds GenericCSV Attribute Error:
ValueError: time data '"2016-12-31' does not match format '%m/%d/%Y'
He obviously fixed it by providing the right datetime format string: https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior
-
thanks.. I noticed that and made the correction. I was hoping that he ran into a problem that has puzzled me for a bit. Here is the code that reproduces the problem for me. I simply modified the above code to keep it clean. The customized datafeeder is not recognized. It's not a typo, but must be something else I am missing???
thanks again as always,
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_ttm',) # openinterest in GenericCSVData has index 7 ... add 1 # add the parameter to the parameters inherited from the base class params = (('pe_ttm', 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_ttm 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.GenericCSV_PE( # data = btfeeds.GenericCSVData( dataname='E:\\Michael\\R\\Stocks\\300Index_New_Combined_Corrected\\000001.csv', nullvalue=0.0, dtformat=('%Y-%m-%d'), datetime=0, time=-1, high=2, low=3, open=1, close=4, volume=5, openinterest=-1, pe_ttm = 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')
error output:
AttributeError Traceback (most recent call last) <ipython-input-21-26c81b63c6dc> in <module>() 51 52 ---> 53 data = btfeeds.GenericCSV_PE( 54 # data = btfeeds.GenericCSVData( 55 dataname='E:\\Michael\\R\\Stocks\\300Index_New_Combined_Corrected\\000001.csv', AttributeError: module 'backtrader.feeds' has no attribute 'GenericCSV_PE'
-
@michael172 said in Extending Datafeeds GenericCSV Attribute Error:
AttributeError: module 'backtrader.feeds' has no attribute 'GenericCSV_PE'
@michael172 said in Extending Datafeeds GenericCSV Attribute Error:
if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() data = btfeeds.GenericCSV_PE( # data = btfeeds.GenericCSVData(
@michael172 said in Extending Datafeeds GenericCSV Attribute Error:
class GenericCSV_PE(GenericCSVData): # Add a 'pe' line to the inherited ones from the base class lines = ('pe_ttm',)
This is something you define.
The original answer does still apply
@backtrader said in Extending Datafeeds GenericCSV Attribute Error:
@Osofuego said in Extending Datafeeds GenericCSV Attribute Error:
data = btfeeds.GenericCSVData(
You are not using your own extended data feed.
-
Ha! Finally figured out two things! One: why my own data feeder wasn't getting accepted and Two: who the bigger idiot is... hopefully was. Thanks for helping out.. saved a lot of my time.
-
@michael172 Hi there, I'm having the same issue that you did: the error message "module 'backtrader.feeds' has no attribute 'symbolroll'" (symbolroll being my own creation). So I think my data feeder isn't being accepted. Could you perhaps share your code or portion of your code that you changed to solve the issue? Many thanks!
@Osofuego Could you share what changes to Michael's code would have fixed this issue? Many thanks again!
-