Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    Backtrader Target Values Example Error Message

    Indicators/Strategies/Analyzers
    2
    3
    1228
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      samk last edited by

      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()
      
      B 1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators @samk last edited by

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

        1 Reply Last reply Reply Quote 0
        • S
          samk last edited by

          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()
          
          1 Reply Last reply Reply Quote 0
          • 1 / 1
          • First post
            Last post
          Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors