Backtrader Target Values Example Error Message



  • Hello,

    I am attempting to run the sample code from:

    https://www.backtrader.com/docu/order_target/order_target.html

    and receiving the following error:

    Traceback (most recent call last):
    File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Target Values & Stop Order.py", line 217, in <module>
    runstrat()
    File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Target Values & Stop Order.py", line 115, in runstrat
    args = parse_args(args)
    File "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Target Values & Stop Order.py", line 192, in parse_args
    help=('Use order_target_size'))
    File "C:\Users\Sam\Anaconda64Best\lib\argparse.py", line 1348, in add_argument
    return self._add_action(action)
    File "C:\Users\Sam\Anaconda64Best\lib\argparse.py", line 1571, in _add_action
    raise ValueError(msg)
    ValueError: mutually exclusive arguments must be optional

    I have tried to set:

    pgroup = parser.add_mutually_exclusive_group(required=True)
    

    to both True, False, and None. But error keeps coming up.

    I have set target size to = true for both of the following lines in the code:

    params = (                          # define target size, value, or percent as order type
            ('use_target_size', True),
            ('use_target_value', False),
            ('use_target_percent', False),
        )
    

    and

    pgroup.add_argument('--target-size', required=True, action='store_true', # use target size
                            help=('Use order_target_size'))
    
        pgroup.add_argument('--target-value', required=False, action='store_true', # use target value
                            help=('Use order_target_value'))
    
        pgroup.add_argument('--target-percent', required=False, # use target percentage
                            action='store_true',
                            help=('Use order_target_percent'))
    

    Error still comes up though for the mutually exclusive thing. Am I missing something in terms of not setting something to True or to None that still needs to be set? Thanks a lot in advance. Entire code is below for reference:

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import argparse
    import datetime  # For datetime objects
    from datetime import datetime
    
    import backtrader as bt
    import backtrader.feeds as btfeeds
    
    
    class TheStrategy(bt.Strategy):
        '''
        This strategy is loosely based on some of the examples from the Van
        K. Tharp book: *Trade Your Way To Financial Freedom*. The logic:
    
          - Enter the market if:
            - The MACD.macd line crosses the MACD.signal line to the upside
            - The Simple Moving Average has a negative direction in the last x
              periods (actual value below value x periods ago)
    
         - Set a stop price x times the ATR value away from the close
    
         - If in the market:
    
           - Check if the current close has gone below the stop price. If yes,
             exit.
           - If not, update the stop price if the new stop price would be higher
             than the current
    
    
    
             # The logic in the sample is rather dumb and only meant for testing:
    
                During odd months (Jan, Mar, ...), use the day as TARGET (in the case of order_target_value multiplying the day by 1000)
    
                This mimics an increasing target
                During even months (Feb, Apr, ...) use 31 - day as the TARGET
    
                This mimics an decreasing target
        '''
    
        params = (                          # define target size, value, or percent as order type
            ('use_target_size', True),
            ('use_target_value', False),
            ('use_target_percent', False),
        )
    
        def notify_order(self, order):
            if order.status == order.Completed:
                pass
    
            if not order.alive():
                self.order = None  # indicate no order is pending
    
        def start(self):
            self.order = None  # sentinel to avoid operations on pending order
    
        def next(self):
            dt = self.data.datetime.date()
    
            portfolio_value = self.broker.get_value()
            print('%04d - %s - Position Size:     %02d - Value %.2f' %
                  (len(self), dt.isoformat(), self.position.size, portfolio_value))
    
            data_value = self.broker.get_value([self.data]) # portfolio value for that specific stock
    
            if self.p.use_target_value: # if we use target value as order execution
                print('%04d - %s - data value %.2f' %
                      (len(self), dt.isoformat(), data_value))
    
            elif self.p.use_target_percent: # if we use target percentage as order execution
                port_perc = data_value / portfolio_value
                print('%04d - %s - data percent %.2f' %
                      (len(self), dt.isoformat(), port_perc))
    
            if self.order: # if order is placed
                return  # pending order execution
    
            size = dt.day # size of order is based on the day (odd or even months)
            if (dt.month % 2) == 0:
                size = 31 - size # if it is an even month, use 31 - day as the target (for odd months, use the day as the target)
    
    
    
           # determine if we base our order on either: target size, target value, or target percentage
    
    
            if self.p.use_target_size: # if we use target size as the order execution
                target = size # target is the size of the trade (number of shares)
                print('%04d - %s - Order Target Size: %02d' %
                      (len(self), dt.isoformat(), size)) # based on size
    
                self.order = self.order_target_size(target=size) # place order based on order target size (number of shares)
    
            elif self.p.use_target_value: # if we use target value, target value = size (number of shares * 1000) as we are multiplying the day by 1000
                value = size * 1000
    
                print('%04d - %s - Order Target Value: %.2f' %
                      (len(self), dt.isoformat(), value)) # based on value
    
                self.order = self.order_target_value(target=value)
    
            elif self.p.use_target_percent: # if we use target percentage of portfolio to place orders (number of shares (size) divided by 100 to see what % of the portfolio it is)
                percent = size / 100.0
    
                print('%04d - %s - Order Target Percent: %.2f' %
                      (len(self), dt.isoformat(), percent)) # based on percentage
    
                self.order = self.order_target_percent(target=percent)
    
    
    def runstrat(args=None):
        args = parse_args(args)
    
        cerebro = bt.Cerebro()
        cerebro.broker.setcash(args.cash) # set brokerage cash value
    
        dkwargs = dict()
        if args.fromdate is not None:
            dkwargs['fromdate'] = datetime.strptime(args.fromdate, "%m/%d/%Y")
        if args.todate is not None:
            dkwargs['todate'] = datetime.strptime(args.todate, "%m/%d/%Y")
    
        # data
        data = btfeeds.GenericCSVData(
            dataname='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.csv',
    
            fromdate=datetime.datetime.strptime("1/1/2000", "%m/%d/%Y"),
            todate=datetime.datetime.strptime("12/31/2000", "%m/%d/%Y"),
    
            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,
    
        )
        cerebro.adddata(data)
    
        # strategy
        cerebro.addstrategy(TheStrategy,
                            use_target_size=args.target_size,
                            use_target_value=args.target_value,
                            use_target_percent=args.target_percent)
    
        cerebro.run()
    
        if args.plot: # plot strategy
            pkwargs = dict(style='bar')
            if args.plot is not True:  # evals to True but is not True
                npkwargs = eval('dict(' + args.plot + ')')  # args were passed
                pkwargs.update(npkwargs)
    
            cerebro.plot(**pkwargs)
    
    
    def parse_args(pargs=None):
    
        parser = argparse.ArgumentParser(
            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
            description='Sample for Order Target')
    
        parser.add_argument('--data', required=False,
                            default='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.csv',
                            help='Specific data to be read in')
    
        parser.add_argument('--fromdate', required=False,
                            default='2005-01-01',
                            help='Starting date in MM/DD/YYYY format')
    
        parser.add_argument('--todate', required=False,
                            default='2006-12-31',
                            help='Ending date in MM/DD/YYYY format')
    
        parser.add_argument('--cash', required=False, action='store', # ending cash at end of date
                            type=float, default=1000000,
                            help='Ending date in MM/DD/YYYY format')
    
        pgroup = parser.add_mutually_exclusive_group(required=True)
    
        pgroup.add_argument('--target-size', required=True, action='store_true', # use target size
                            help=('Use order_target_size'))
    
        pgroup.add_argument('--target-value', required=False, action='store_true', # use target value
                            help=('Use order_target_value'))
    
        pgroup.add_argument('--target-percent', required=False, # use target percentage
                            action='store_true',
                            help=('Use order_target_percent'))
    
        # Plot options
        parser.add_argument('--plot', '-p', nargs='?', required=False,
                            metavar='kwargs', const=True,
                            help=('Plot the read data applying any kwargs passed\n'
                                  '\n'
                                  'For example:\n'
                                  '\n'
                                  '  --plot style="candle" (to plot candles)\n'))
    
        if pargs is not None:
            return parser.parse_args(pargs)
    
        return parser.parse_args()
    
    
    if __name__ == '__main__':
        runstrat()
    

  • administrators

    @samk said in Backtrader Target Values Example Error Message:

    I am attempting to run the sample code from:
    https://www.backtrader.com/docu/order_target/order_target.html

    No you are not. You are running a modified version, hence the error.

    @samk said in Backtrader Target Values Example Error Message:

        pgroup.add_argument('--target-size', required=True, action='store_true', # use target size
                            help=('Use order_target_size'))
    
        pgroup.add_argument('--target-value', required=False, action='store_true', # use target value
                            help=('Use order_target_value'))
    
        pgroup.add_argument('--target-percent', required=False, # use target percentage
                            action='store_true',
                            help=('Use order_target_percent'))
    

    At leas there the code has been modified.



  • Below is the original code pasted from the site exactly as it is. Getting error:

    C:\Users\Sam\Anaconda64Best\python.exe "C:/Users/Sam/PycharmProjects/Test/.ipynb_checkpoints/Backtrader Target Value Example.py"
    usage: Backtrader Target Value Example.py [-h] [--data DATA]
    [--fromdate FROMDATE]
    [--todate TODATE] [--cash CASH]
    (--target-size | --target-value | --target-percent)
    [--plot [kwargs]]
    Backtrader Target Value Example.py: error: one of the arguments --target-size --target-value --target-percent is required

    I have tried to set either size, target value, or target percent to 'True' to from its current default 'False' to try to resolve in the block of code:

     params = (                          # define target size, value, or percent as order type
            ('use_target_size', False),
            ('use_target_value', False),
            ('use_target_percent', False),
        )
    

    However, error still comes up. Is there somewhere else in the code that needs to be set to 'True' instead that I am not seeing and changing? Thanks for the help in advance. Full code is below from the website:

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import argparse
    import datetime  # For datetime objects
    from datetime import datetime
    
    import backtrader as bt
    import backtrader.feeds as btfeeds
    
    
    class TheStrategy(bt.Strategy):
        '''
        This strategy is loosely based on some of the examples from the Van
        K. Tharp book: *Trade Your Way To Financial Freedom*. The logic:
    
          - Enter the market if:
            - The MACD.macd line crosses the MACD.signal line to the upside
            - The Simple Moving Average has a negative direction in the last x
              periods (actual value below value x periods ago)
    
         - Set a stop price x times the ATR value away from the close
    
         - If in the market:
    
           - Check if the current close has gone below the stop price. If yes,
             exit.
           - If not, update the stop price if the new stop price would be higher
             than the current
    
    
    
             # The logic in the sample is rather dumb and only meant for testing:
    
                During odd months (Jan, Mar, ...), use the day as TARGET (in the case of order_target_value multiplying the day by 1000)
    
                This mimics an increasing target
                During even months (Feb, Apr, ...) use 31 - day as the TARGET
    
                This mimics an decreasing target
        '''
    
        params = (                          # define target size, value, or percent as order type
            ('use_target_size', False),
            ('use_target_value', False),
            ('use_target_percent', False),
        )
    
        def notify_order(self, order):
            if order.status == order.Completed:
                pass
    
            if not order.alive():
                self.order = None  # indicate no order is pending
    
        def start(self):
            self.order = None  # sentinel to avoid operations on pending order
    
        def next(self):
            dt = self.data.datetime.date()
    
            portfolio_value = self.broker.get_value()
            print('%04d - %s - Position Size:     %02d - Value %.2f' %
                  (len(self), dt.isoformat(), self.position.size, portfolio_value))
    
            data_value = self.broker.get_value([self.data]) # portfolio value for that specific stock
    
            if self.p.use_target_value: # if we use target value as order execution
                print('%04d - %s - data value %.2f' %
                      (len(self), dt.isoformat(), data_value))
    
            elif self.p.use_target_percent: # if we use target percentage as order execution
                port_perc = data_value / portfolio_value
                print('%04d - %s - data percent %.2f' %
                      (len(self), dt.isoformat(), port_perc))
    
            if self.order: # if order is placed
                return  # pending order execution
    
            size = dt.day # size of order is based on the day (odd or even months)
            if (dt.month % 2) == 0:
                size = 31 - size # if it is an even month, use 31 - day as the target (for odd months, use the day as the target)
    
    
    
           # determine if we base our order on either: target size, target value, or target percentage
    
    
            if self.p.use_target_size: # if we use target size as the order execution
                target = size # target is the size of the trade (number of shares)
                print('%04d - %s - Order Target Size: %02d' %
                      (len(self), dt.isoformat(), size)) # based on size
    
                self.order = self.order_target_size(target=size) # place order based on order target size (number of shares)
    
            elif self.p.use_target_value: # if we use target value, target value = size (number of shares * 1000) as we are multiplying the day by 1000
                value = size * 1000
    
                print('%04d - %s - Order Target Value: %.2f' %
                      (len(self), dt.isoformat(), value)) # based on value
    
                self.order = self.order_target_value(target=value)
    
            elif self.p.use_target_percent: # if we use target percentage of portfolio to place orders (number of shares (size) divided by 100 to see what % of the portfolio it is)
                percent = size / 100.0
    
                print('%04d - %s - Order Target Percent: %.2f' %
                      (len(self), dt.isoformat(), percent)) # based on percentage
    
                self.order = self.order_target_percent(target=percent)
    
    
    def runstrat(args=None):
        args = parse_args(args)
    
        cerebro = bt.Cerebro()
        cerebro.broker.setcash(args.cash) # set brokerage cash value
    
        dkwargs = dict()
        if args.fromdate is not None:
            dkwargs['fromdate'] = datetime.strptime(args.fromdate, "%m/%d/%Y")
        if args.todate is not None:
            dkwargs['todate'] = datetime.strptime(args.todate, "%m/%d/%Y")
    
        # data
        data = btfeeds.GenericCSVData(
            dataname='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.csv',
    
            fromdate=datetime.datetime.strptime("1/1/2000", "%m/%d/%Y"),
            todate=datetime.datetime.strptime("12/31/2000", "%m/%d/%Y"),
    
            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,
    
        )
        cerebro.adddata(data)
    
        # strategy
        cerebro.addstrategy(TheStrategy,
                            use_target_size=args.target_size,
                            use_target_value=args.target_value,
                            use_target_percent=args.target_percent)
    
        cerebro.run()
    
        if args.plot: # plot strategy
            pkwargs = dict(style='bar')
            if args.plot is not True:  # evals to True but is not True
                npkwargs = eval('dict(' + args.plot + ')')  # args were passed
                pkwargs.update(npkwargs)
    
            cerebro.plot(**pkwargs)
    
    
    def parse_args(pargs=None):
    
        parser = argparse.ArgumentParser(
            formatter_class=argparse.ArgumentDefaultsHelpFormatter,
            description='Sample for Order Target')
    
        parser.add_argument('--data', required=False,
                            default='C:\\Users\\Sam\\PycharmProjects\\Test\\.ipynb_checkpoints\\orcl-1995-2014.csv', # set file path
                            help='Specific data to be read in')
    
        parser.add_argument('--fromdate', required=False,
                            default='2005-01-01',
                            help='Starting date in MM/DD/YYYY format') # set file format
    
        parser.add_argument('--todate', required=False,
                            default='2006-12-31',
                            help='Ending date in MM/DD/YYYY format')  # set file format
    
        parser.add_argument('--cash', required=False, action='store', # ending cash at end of date
                            type=float, default=1000000,
                            help='Ending date in MM/DD/YYYY format')  # set file format
    
        pgroup = parser.add_mutually_exclusive_group(required=True)
    
        pgroup.add_argument('--target-size', required=False, action='store_true', # use target size
                            help=('Use order_target_size'))
    
        pgroup.add_argument('--target-value', required=False, action='store_true', # use target value
                            help=('Use order_target_value'))
    
        pgroup.add_argument('--target-percent', required=False, # use target percentage
                            action='store_true',
                            help=('Use order_target_percent'))
    
        # Plot options
        parser.add_argument('--plot', '-p', nargs='?', required=False,
                            metavar='kwargs', const=True,
                            help=('Plot the read data applying any kwargs passed\n'
                                  '\n'
                                  'For example:\n'
                                  '\n'
                                  '  --plot style="candle" (to plot candles)\n'))
    
        if pargs is not None:
            return parser.parse_args(pargs)
    
        return parser.parse_args()
    
    
    if __name__ == '__main__':
        runstrat()
    

Log in to reply
 

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