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()
    
    

  • administrators

    @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()
    
    ` ` `

  • administrators

    @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 from Quandl)



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

    Process 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())
    ` ` `

  • administrators

    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:

    0_1507674079610_Capture.PNG

    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 NoneType

    I 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())
    

  • administrators

    @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 with dtformat=('%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.00

    Process 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:

    0_1507682320185_Capture.PNG



  • Maybe the problem is in the incorrect use of datetime.datetime.
    This is correct way

            fromdate=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


  • administrators

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

    Process finished with exit code 1

    Again, the data I am trying to extra is from the file in the format of:

    0_1507698170126_Capture.PNG

    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())
    


  • @backtrader @ab_trader

    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:

    1. datetime.datetime(2000-1-1)

    or

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


  • administrators

    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


Log in to reply
 

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