MultiData Strategy Does not Work
-
Hello,
https://www.backtrader.com/blog/posts/2015-09-03-multidata-strategy/multidata-strategy.html
Does not seem to work. I am not sure why every documentation and blog post I see is still using Yahoo and not Google when Yahoo no longer is active? Confused on that. Anyhow, when I run your code on python 3, I get this error:
C:\Users\Sam\Anaconda64Best\python.exe "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Pair Trading Strategy.py"
Traceback (most recent call last):
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Pair Trading Strategy.py", line 174, in <module>
runstrategy()
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Pair Trading Strategy.py", line 126, in runstrategy
cerebro.run()
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\cerebro.py", line 1142, in run
runstrat = self.runstrategies(iterstrat)
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\cerebro.py", line 1224, in runstrategies
data.preload()
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 685, in preload
while self.load():
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 476, in load
_loadret = self._load()
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 707, in _load
return self._loadline(linetokens)
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feeds\yahoo.py", line 128, in _loadline
dt = date(int(dttxt[0:4]), int(dttxt[5:7]), int(dttxt[8:10]))
ValueError: invalid literal for int() with base 10: ''CODE BELOW:
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import datetime # The above could be sent to an independent module import backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind class MultiDataStrategy(bt.Strategy): ''' This strategy operates on 2 datas. The expectation is that the 2 datas are correlated and the 2nd data is used to generate signals on the 1st - Buy/Sell Operationss will be executed on the 1st data - The signals are generated using a Simple Moving Average on the 2nd data when the close price crosses upwwards/downwards The strategy is a long-only strategy ''' params = dict( period=15, stake=10, printout=True, ) def log(self, txt, dt=None): if self.p.printout: dt = dt or self.data.datetime[0] dt = bt.num2date(dt) print('%s, %s' % (dt.isoformat(), txt)) def notify_order(self, order): if order.status in [bt.Order.Submitted, bt.Order.Accepted]: return # Await further notifications if order.status == order.Completed: if order.isbuy(): buytxt = 'BUY COMPLETE, %.2f' % order.executed.price self.log(buytxt, order.executed.dt) else: selltxt = 'SELL COMPLETE, %.2f' % order.executed.price self.log(selltxt, order.executed.dt) elif order.status in [order.Expired, order.Canceled, order.Margin]: self.log('%s ,' % order.Status[order.status]) pass # Simply log # Allow new orders self.orderid = None def __init__(self): # To control operation entries self.orderid = None # Create SMA on 2nd data sma = btind.MovAv.SMA(self.data1, period=self.p.period) # Create a CrossOver Signal from close an moving average self.signal = btind.CrossOver(self.data1.close, sma) def next(self): if self.orderid: return # if an order is active, no new orders are allowed if not self.position: # not yet in market if self.signal > 0.0: # cross upwards self.log('BUY CREATE , %.2f' % self.data1.close[0]) self.buy(size=self.p.stake) else: # in the market if self.signal < 0.0: # crosss downwards self.log('SELL CREATE , %.2f' % self.data1.close[0]) self.sell(size=self.p.stake) def stop(self): print('==================================================') print('Starting Value - %.2f' % self.broker.startingcash) print('Ending Value - %.2f' % self.broker.getvalue()) print('==================================================') def runstrategy(): args = parse_args() # Create a cerebro cerebro = bt.Cerebro() # Get the dates from the args fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') # Create the 1st data data0 = btfeeds.YahooFinanceCSVData( dataname=args.data0, fromdate=fromdate, todate=todate) # Add the 1st data to cerebro cerebro.adddata(data0) # Create the 2nd data data1 = btfeeds.YahooFinanceCSVData( dataname=args.data1, fromdate=fromdate, todate=todate) # Add the 2nd data to cerebro cerebro.adddata(data1) # Add the strategy cerebro.addstrategy(MultiDataStrategy, period=args.period, stake=args.stake) # Add the commission - only stocks like a for each operation cerebro.broker.setcash(args.cash) # Add the commission - only stocks like a for each operation cerebro.broker.setcommission(commission=args.commperc) # And run it cerebro.run() # Plot if requested if args.plot: cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False) def parse_args(): parser = argparse.ArgumentParser(description='MultiData Strategy') parser.add_argument('--data0', '-d0', default='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt', help='1st data into the system') parser.add_argument('--data1', '-d1', default='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\yhoo-1996-2014.txt', help='2nd data into the system') parser.add_argument('--fromdate', '-f', default='2003-01-01', help='Starting date in YYYY-MM-DD format') parser.add_argument('--todate', '-t', default='2005-12-31', help='Starting date in YYYY-MM-DD format') parser.add_argument('--period', default=15, type=int, help='Period to apply to the Simple Moving Average') parser.add_argument('--cash', default=100000, type=int, help='Starting Cash') parser.add_argument('--commperc', default=0.005, type=float, help='Percentage commission for operation (0.005 is 0.5%%') parser.add_argument('--stake', default=10, type=int, help='Stake to apply in each operation') parser.add_argument('--plot', '-p', action='store_true', help='Plot the read data') parser.add_argument('--numfigs', '-n', default=1, help='Plot using numfigs figures') return parser.parse_args() if __name__ == '__main__': runstrategy()
-
@samk said in MultiData Strategy Does not Work:
Does not seem to work. I am not sure why every documentation and blog post I see is still using Yahoo and not Google when Yahoo no longer is active?
Because the documentation and blog posts were done when Yahoo was active. And there is no data feed for downloading from Google.
You may choose any other data feed (including generic configurable CSV data files)
@samk said in MultiData Strategy Does not Work:
ValueError: invalid literal for int() with base 10: ''
In any case the error indicates that a double quote
"
was found there were only numbers (and hyphens) are to be expected.You could also post a couple of lines of the data.
-
So what is the fix to this? I cannot run this code beacause it is using :
data1 = btfeeds.YahooFinanceCSVData(
and
data0 = btfeeds.YahooFinanceCSVData(I assume? I do not see where the double quotes in my code are that you mention.
Am I able to even run this code on python 3? which is what i am trying to do.
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import datetime # The above could be sent to an independent module import backtrader as bt import backtrader.feeds as btfeeds import backtrader.indicators as btind class MultiDataStrategy(bt.Strategy): ''' This strategy operates on 2 datas. The expectation is that the 2 datas are correlated and the 2nd data is used to generate signals on the 1st - Buy/Sell Operationss will be executed on the 1st data - The signals are generated using a Simple Moving Average on the 2nd data when the close price crosses upwwards/downwards The strategy is a long-only strategy ''' params = dict( period=15, stake=10, printout=True, ) def log(self, txt, dt=None): if self.p.printout: dt = dt or self.data.datetime[0] dt = bt.num2date(dt) print('%s, %s' % (dt.isoformat(), txt)) def notify_order(self, order): if order.status in [bt.Order.Submitted, bt.Order.Accepted]: return # Await further notifications if order.status == order.Completed: if order.isbuy(): buytxt = 'BUY COMPLETE, %.2f' % order.executed.price self.log(buytxt, order.executed.dt) else: selltxt = 'SELL COMPLETE, %.2f' % order.executed.price self.log(selltxt, order.executed.dt) elif order.status in [order.Expired, order.Canceled, order.Margin]: self.log('%s ,' % order.Status[order.status]) pass # Simply log # Allow new orders self.orderid = None def __init__(self): # To control operation entries self.orderid = None # Create SMA on 2nd data sma = btind.MovAv.SMA(self.data1, period=self.p.period) # Create a CrossOver Signal from close an moving average self.signal = btind.CrossOver(self.data1.close, sma) def next(self): if self.orderid: return # if an order is active, no new orders are allowed if not self.position: # not yet in market if self.signal > 0.0: # cross upwards self.log('BUY CREATE , %.2f' % self.data1.close[0]) self.buy(size=self.p.stake) else: # in the market if self.signal < 0.0: # crosss downwards self.log('SELL CREATE , %.2f' % self.data1.close[0]) self.sell(size=self.p.stake) def stop(self): print('==================================================') print('Starting Value - %.2f' % self.broker.startingcash) print('Ending Value - %.2f' % self.broker.getvalue()) print('==================================================') def runstrategy(): args = parse_args() # Create a cerebro cerebro = bt.Cerebro() # Get the dates from the args fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') # Create the 1st data data0 = btfeeds.YahooFinanceCSVData( dataname=args.data0, fromdate=fromdate, todate=todate) # Add the 1st data to cerebro cerebro.adddata(data0) # Create the 2nd data data1 = btfeeds.YahooFinanceCSVData( dataname=args.data1, fromdate=fromdate, todate=todate) # Add the 2nd data to cerebro cerebro.adddata(data1) # Add the strategy cerebro.addstrategy(MultiDataStrategy, period=args.period, stake=args.stake) # Add the commission - only stocks like a for each operation cerebro.broker.setcash(args.cash) # Add the commission - only stocks like a for each operation cerebro.broker.setcommission(commission=args.commperc) # And run it cerebro.run() # Plot if requested if args.plot: cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False) def parse_args(): parser = argparse.ArgumentParser(description='MultiData Strategy') parser.add_argument('--data0', '-d0', default='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt', help='1st data into the system') parser.add_argument('--data1', '-d1', default='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\yhoo-1996-2014.txt', help='2nd data into the system') parser.add_argument('--fromdate', '-f', default='2003-01-01', help='Starting date in YYYY-MM-DD format') parser.add_argument('--todate', '-t', default='2005-12-31', help='Starting date in YYYY-MM-DD format') parser.add_argument('--period', default=15, type=int, help='Period to apply to the Simple Moving Average') parser.add_argument('--cash', default=100000, type=int, help='Starting Cash') parser.add_argument('--commperc', default=0.005, type=float, help='Percentage commission for operation (0.005 is 0.5%%') parser.add_argument('--stake', default=10, type=int, help='Stake to apply in each operation') parser.add_argument('--plot', '-p', action='store_true', help='Plot the read data') parser.add_argument('--numfigs', '-n', default=1, help='Plot using numfigs figures') return parser.parse_args() if __name__ == '__main__': runstrategy() ` ` `
-
@samk said in MultiData Strategy Does not Work:
I do not see where the double quotes in my code are that you mention.
They are not in the code. They are in the data, hence the error.
@backtrader said in MultiData Strategy Does not Work:
ValueError: invalid literal for int() with base 10: ''
(It might also be that it is simple two consecutive single quotes)
And the statement
@backtrader said in MultiData Strategy Does not Work:
You could also post a couple of lines of the data.
Although the major problem with the latest known method with Yahoo is that data will be altered at random places. The double quotes (or empty field if two single quotes) might actually be anywhere in the file, which would mean you have to clean the file.
@samk said in MultiData Strategy Does not Work:
Am I able to even run this code on python 3?
People use it with Python 2.7 and 3.2+.
After the Yahoo demise the best option is to look for alternative data sources. The
pandas
team was looking for a solution which would involve multiple downloads of the Yahoo data to make sure that the surprises introduced by Yahoo could be corrected. This obviously would increase loading time. You may try to find if they succeeded.Quandl
's wiki data is also supported (and any other non-wiki, which has also the same CSV format fromQuandl
) -
Well , I have taken yahoo out and simply reading in the oracle file you guys had posted in the following short code, and still getting an error:
C:\Users\Sam\Anaconda64Best\python.exe "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Examples.py"
Traceback (most recent call last):
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Examples.py", line 57, in <module>
volume=5,
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\metabase.py", line 89, in call
_obj, args, kwargs = cls.dopostinit(_obj, *args, **kwargs)
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 637, in dopostinit
_obj._name, _ = os.path.splitext(os.path.basename(_obj.p.dataname))
File "C:\Users\Sam\Anaconda64Best\lib\ntpath.py", line 235, in basename
return split(p)[1]
File "C:\Users\Sam\Anaconda64Best\lib\ntpath.py", line 204, in split
p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not NoneTypeProcess finished with exit code 1
The code is as follows:
` ` ` from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) from backtrader.feeds import GenericCSVData import backtrader.indicators as btind import backtrader.feeds as btfeeds import backtrader as bt # Import the backtrader platform import backtrader as bt # 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): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere modpath = os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.join(modpath, 'C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt') # Create a Data Feed data = btfeeds.GenericCSVData( nullvalue=0.0, dtformat=('%m/%d/%Y'), datetime=0, open=1, high=2, low=3, adjclose=4, volume=5, ) # 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()) ` ` `
-
Sorry I meant:
` ` ` from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) from backtrader.feeds import GenericCSVData import backtrader.indicators as btind import backtrader.feeds as btfeeds import backtrader as bt # Import the backtrader platform import backtrader as bt # 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): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere modpath = os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.join(modpath, 'C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt') # Create a Data Feed data = btfeeds.GenericCSVData( nullvalue=0.0, dtformat=('%Y/%m/%d'), datetime=0, open=1, high=2, low=3, adjclose=4, volume=5, ) # 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()) ` ` `
-
dataname
is not being specified to the data feed.@samk said in MultiData Strategy Does not Work:
_obj._name, _ = os.path.splitext(os.path.basename(_obj.p.dataname)) File "C:\Users\Sam\Anaconda64Best\lib\ntpath.py", line 235, in basename return split(p)[1] File "C:\Users\Sam\Anaconda64Best\lib\ntpath.py", line 204, in split p = os.fspath(p) TypeError: expected str, bytes or os.PathLike object, not NoneType
It's crystal clear in the error messages you post, but it's easier to assign the error to the framework.
@samk said in MultiData Strategy Does not Work:
and still getting an error
It's for sure not the same error.
-
I do not see why I am getting this error still. I am using the code from github with the file 'orcl-1995-2014.txt'. Image of it attached below:
ERROR MESSAGE STILL:
Traceback (most recent call last):
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Examples.py", line 56, in <module>
volume=5,
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\metabase.py", line 89, in call
_obj, args, kwargs = cls.dopostinit(_obj, *args, **kwargs)
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 637, in dopostinit
_obj._name, _ = os.path.splitext(os.path.basename(_obj.p.dataname))
File "C:\Users\Sam\Anaconda64Best\lib\ntpath.py", line 235, in basename
return split(p)[1]
File "C:\Users\Sam\Anaconda64Best\lib\ntpath.py", line 204, in split
p = os.fspath(p)
TypeError: expected str, bytes or os.PathLike object, not NoneTypeI have modified the code to match dataname across my code. Please see revised code below:
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) from backtrader.feeds import GenericCSVData import backtrader.indicators as btind import backtrader.feeds as btfeeds import backtrader as bt # 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): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere modpath = os.path.dirname(os.path.abspath(sys.argv[0])) data = os.path.join(modpath, 'C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt') # Create a Data Feed data = btfeeds.GenericCSVData( nullvalue=0.0, dtformat=('%Y/%m/%d'), datetime=0, open=1, high=2, low=3, adjclose=4, volume=5, ) # 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())
-
@samk said in MultiData Strategy Does not Work:
# Create a Data Feed data = btfeeds.GenericCSVData( nullvalue=0.0, dtformat=('%Y/%m/%d'), datetime=0, open=1, high=2, low=3, adjclose=4, volume=5, )
Look for all samples and see that a
dataname
parameter is given to data feeds. Clearly missing there and clearly indicated in the error messages.In any case
1995-01-03
is clearly bound to fail withdtformat=('%Y/%m/%d')
@samk said in MultiData Strategy Does not Work:
am using the code from github
No, you are not.
-
Ok, thanks looks like I figured it out.
I got the following output:
C:\Users\Sam\Anaconda64Best\python.exe "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Examples.py"
Starting Portfolio Value: 100000.00
Final Portfolio Value: 100000.00Process finished with exit code 0
Does this seem ok now (my code that is pasted below). Sorry I am new and just want to make sure given this output that I corrected accordingly.
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) from backtrader.feeds import GenericCSVData import backtrader.indicators as btind import backtrader.feeds as btfeeds import backtrader as bt # Create a Strategy 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): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere data = btfeeds.GenericCSVData(dataname='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt') cerebro = bt.Cerebro() # 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())
-
@backtrader said in MultiData Strategy Does not Work:
In any case 1995-01-03 is clearly bound to fail with dtformat=('%Y/%m/%d')
In regads to what you said above. I am confused, because dtformat=('%Y/%m/%d') is in the format of year, then month, then day. which matches 1995-01-03 (year, month, date).
Thus why is this failing? Can you please advise what I need to change 'dtformate=' so that it matches 1995-01-03 format?
Thanks in advance.
-
Still having trouble, even when it change it to:
fromdate=datetime.datetime(2000-1-1),
todate=datetime.datetime(2000-12-31),dtformat=('%Y-%m-%d'),
I get the error:
Traceback (most recent call last):
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Sample SMA Strategy.py", line 53, in <module>
fromdate=datetime.datetime(2000-1-1),
TypeError: Required argument 'month' (pos 2) not found -
Original file:
data = btfeeds.GenericCSVData( dataname='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.txt', fromdate=datetime.datetime(2000-1-1), todate=datetime.datetime(2000-12-31), nullvalue=0.0, dtformat=('%Y-%m-%d'), datetime=0, open=1, high=2, low=3, close=4, adjClose=5, volume=6, )
Trying to incorporate:
-
Maybe the problem is in the incorrect use of
datetime.datetime
.
This is correct wayfromdate=datetime.datetime(2000,1,1) todate=datetime.datetime(2000,12,31)
or
fromdate=datetime.datetime.strptime("2000-1-1", "%Y-%m-%d") todate=datetime.datetime.strptime("2000-12-31", "%Y-%m-%d")
if you want operate with strings
-
@samk said in MultiData Strategy Does not Work:
Still having trouble, even when it change it to:
fromdate=datetime.datetime(2000-1-1),
todate=datetime.datetime(2000-12-31),
dtformat=('%Y-%m-%d'),You seem to be in a quick rush to put things together, but it seems the basics are completely missing. The suggested reading: Python Documentation - 8.1. datetime — Basic date and time types
This construct (and the inability to read simple error messages)
datetime.datetime(2000-1-1)
is a clear symptom that some polishing of Python may be needed.
-
Thank you very much for the help. Yes I tried:
datetime.datetime(2000-1-1)
after reading up on some documentation and it resolved that error. Only to now be receiving a new error:
Traceback (most recent call last):
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Sample SMA Strategy.py", line 53, in <module>
fromdate=datetime.datetime(2000-1-1),
TypeError: Required argument 'month' (pos 2) not foundProcess finished with exit code 1
Again, the data I am trying to extra is from the file in the format of:
My full code for the strategy is shown below. its very odd why I am getting this error. Any idea by any chance what it could be?
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects 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 # 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.txt', fromdate=datetime.datetime(2000-1-3), # these are dates available in the .txt file todate=datetime.datetime(2000-12-29), # these are dates available in the .txt file nullvalue=0.0, # missing values to be replaced with 0 dtformat=('%Y-%m-%d'), datetime=0, open=1, high=2, low=3, close=4, adj_close=5, volume=6, ) # 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())
-
@samk you still use datetime.datetime call incorrectly. Read my previous post.
-
@ab_trader said in MultiData Strategy Does not Work:
fromdate=datetime.datetime.strptime("2000-1-1", "%Y-%m-%d")
todate=datetime.datetime.strptime("2000-12-31", "%Y-%m-%d")I used it in the way that backtrader just suggested and got that error i just posted. if i use it in any way that you suggested (any of the 2 you suggested, it still wont work). I get the error:
File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Sample SMA Strategy.py", line 82, in <module>
cerebro.run()
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\cerebro.py", line 1142, in run
runstrat = self.runstrategies(iterstrat)
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\cerebro.py", line 1224, in runstrategies
data.preload()
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 685, in preload
while self.load():
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 476, in load
_loadret = self._load()
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feed.py", line 707, in _load
return self._loadline(linetokens)
File "C:\Users\Sam\Anaconda64Best\lib\site-packages\backtrader\feeds\csvgeneric.py", line 114, in _loadline
dt = datetime.strptime(dtfield, dtformat)
File "C:\Users\Sam\Anaconda64Best\lib_strptime.py", line 565, in _strptime_datetime
tt, fraction = _strptime(data_string, format)
File "C:\Users\Sam\Anaconda64Best\lib_strptime.py", line 362, in _strptime
(data_string, format))
ValueError: time data '' does not match format '%Y-%m-%d'When using it your way. Full code shown below with your way:
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects 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 # 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.txt', fromdate=datetime.datetime.strptime("2000-1-1", "%Y-%m-%d"), todate = datetime.datetime.strptime("2000-12-31", "%Y-%m-%d"), nullvalue=0.0, # missing values to be replaced with 0 dtformat=('%Y-%m-%d'), datetime=0, open=1, high=2, low=3, close=4, adj_close=5, volume=6, ) # 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())
-
Please let me know if you guys see any errors in the code blocks for both of your suggested solutions that seem to not run. Being:
- datetime.datetime(2000-1-1)
or
- fromdate=datetime.datetime.strptime("2000-1-1", "%Y-%m-%d")
todate=datetime.datetime.strptime("2000-12-31", "%Y-%m-%d")
Thank you very much in advance.
-
2000-1-1
means: substract 1 from 2000 and then substract 1 from the previous result.Carrying on with the previous answers:
@samk said in MultiData Strategy Does not Work:
I used it in the way that backtrader just suggested and got that error i just posted
There was no suggestion to do it in any way.
@backtrader said in MultiData Strategy Does not Work:
This construct (and the inability to read simple error messages)
datetime.datetime(2000-1-1)
is a clear symptom that some polishing of Python may be needed.
The clear suggestion is to polish up your Python. At the moment you are not able to instantiate a
datetime.datetime
instance, even if the examples are full of such instantiations. And you are unable to read the error messages, which already show where and why things are failing.Sooner or later (as any would) you will get a running script. But the likelihood of logic failures and the introduction of blatant bugs is very high.
The suggestion again: learn the basics of Python.
Hint:
@samk said in MultiData Strategy Does not Work:
"2000-1-1", "%Y-%m-%d"
Read the documentation because
2000-1-1
is not a suitable format for%Y-%m-%d
. Python Documentation - 8.1. datetime — Basic date and time types