Navigation

    Backtrader Community

    • Register
    • 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/

    ValueError: x and y must have length at least 2.

    General Code/Help
    2
    4
    885
    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.
    • Y
      YELNAr last edited by

      Print error "File "C:\Users\user\Anaconda3\envs\BackTrading\lib\site-packages\scipy\stats\stats.py", line 3392, in pearsonr
      raise ValueError('x and y must have length at least 2.')

      ValueError: x and y must have length at least 2.
      "

        from __future__ import (absolute_import, division, print_function,
                          unicode_literals)
      
        import argparse
        import datetime
      
        import scipy.stats
        import backtrader as bt
        import backtrader.feeds as btfeeds
        import backtrader.indicators as btind
      

      class PairTradingStrategy(bt.Strategy):
      params = dict(
      period20=20,
      period10=10,
      stake=10,
      qty1=0,
      qty2=0,
      status=0,
      )

      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
          self.qty1 = self.p.qty1
          self.qty2 = self.p.qty2
          self.status = self.p.status
          self.profit_fix = 30
          self.profit = 0
          self.cash_aapl = 0
          self.cash_msft = 0
          self.init_close1 = 0
          self.init_close2 = 0
          self.portfolio_value = self.broker.startingcash
      
          # # Signals performed with PD.OLS :
          # self.transform = btind.OLS_TransformationN(self.data0, self.data1,
          #                                            period10=self.p.period10,period20=self.p.period20)
          # self.zscore = self.transform.zscore
      
          # Checking signals built with StatsModel.API :
          # self.ols_transfo = btind.OLS_Transformation(self.data0, self.data1,
          #                                             period=self.p.period,
          #                                             plot=True)
      
      def next(self):
      
          if self.orderid:
              return  # if an order is active, no new orders are allowed
      
          print('*' * 20)
          print('Status is ', self.status)
      
          c10_basket1, p = scipy.stats.pearsonr(self.data0.get(size=self.p.period10),
                                                self.data1.get(size=self.p.period10))
      
          c20_basket1, p = scipy.stats.pearsonr(self.data0.get(size=self.p.period20),
                                                self.data1.get(size=self.p.period20))
          c10_basket1, c20_basket1 = round(c10_basket1, 2), round(c20_basket1, 2)
          self.log('Close, {}'.format(self.datas[0].close[0]))
          self.log('Close, {}'.format(self.datas[1].close[0]))
          print('corr10: {}, corr20: {}'.format(c10_basket1, c20_basket1))
      
          if self.status == 1:
              self.cash_aapl = round((self.data0.close[0] - self.init_close1) * self.qty1, 2)
              self.cash_msft = round((self.init_close2 - self.data1.close[0]) * self.qty2, 2)
              self.profit = round((self.cash_aapl + self.cash_msft), 2)
      
              print('Profit stock1: {}'.format(self.cash_aapl))
              print('Profit stock2: {}'.format(self.cash_msft))
              print('Total profit: {}'.format(self.profit))
      
          if (c10_basket1 > 0.7 and c20_basket1 > 0.7) and (self.status != 1):
      
              # Calculating the number of shares for each stock
              value = 0.5 * self.portfolio_value_basket1  # Divide the cash equally
              x = int(value / (self.data0.close))  # Find the number of shares for Stock1
              y = int(value / (self.data1.close))  # Find the number of shares for Stock2
      
              print('portfolio_value_basket1: {}'.format(self.portfolio_value_basket1))
      
              # Place the order
              self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AAPL", self.data0.close[0], x))
              self.buy(data=self.data0, size=(x))
      
              self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("MSFT", self.data1.close[0], y))
              self.sell(data=self.data1, size=(y))
      
              self.qty1 = x  # The new open position quantity for Stock1 is x shares
              self.qty2 = y  # The new open position quantity for Stock2 is y shares
              self.init_close1 = self.data0.close[0]
              self.init_close2 = self.data1.close[0]
              self.status = 1  # The current status is "long the spread"
      
          elif (self.profit > self.profit_fix) and self.status == 1:
              print('profit: {}, profit_fix: {}'.format(self.profit, self.profit_fix))
              # Placing the order
              self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAPL", self.data0.close[0], self.qty1))
              self.sell(data=self.data0, size=(self.qty1))
      
              self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("MSFT", self.data1.close[0], self.qty2))
              self.buy(data=self.data1, size=(self.qty2))
      
              # Updating the counters with new value
              self.portfolio_value_basket1 += self.profit
              self.qty1, self.qty2 = 0, 0
      
              self.cash_aapl, self.cash_msft, self.profit = 0, 0, 0
      
              self.status = 0
      
      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()
      
      storekwargs = dict(
          host=args.host, port=args.port,
          clientId=args.clientId, timeoffset=not args.no_timeoffset,
          reconnect=args.reconnect, timeout=args.timeout,
          notifyall=args.notifyall, _debug=args.debug
      )
      
      if args.usestore:
          ibstore = bt.stores.IBStore(**storekwargs)
      
      if args.broker:
          if args.usestore:
              broker = ibstore.getbroker()
          else:
              broker = bt.brokers.IBBroker(**storekwargs)
      
          cerebro.setbroker(broker)
      
      timeframe = bt.TimeFrame.TFrame(args.timeframe)
      if args.resample or args.replay:
          datatf = bt.TimeFrame.Ticks
          datacomp = 1
      else:
          datatf = timeframe
          datacomp = args.compression
      
      fromdate = None
      if args.fromdate:
          dtformat = '%Y-%m-%d' + ('T%H:%M:%S' * ('T' in args.fromdate))
          fromdate = datetime.datetime.strptime(args.fromdate, dtformat)
      
      IBDataFactory = ibstore.getdata if args.usestore else bt.feeds.IBData
      
      datakwargs = dict(
          timeframe=datatf, compression=datacomp,
          historical=args.historical, fromdate=fromdate,
          rtbar=args.rtbar,
          qcheck=args.qcheck,
          what=args.what,
          backfill_start=not args.no_backfill_start,
          backfill=not args.no_backfill,
          latethrough=args.latethrough,
          tz=args.timezone
      )
      if not args.usestore and not args.broker:   # neither store nor broker
          datakwargs.update(storekwargs)  # pass the store args over the data
      
      data0 = IBDataFactory(dataname=args.data0, **datakwargs)
      
      data1 = IBDataFactory(dataname=args.data1, **datakwargs)
      
      
      rekwargs = dict(
          timeframe=timeframe, compression=args.compression,
          bar2edge=not args.no_bar2edge,
          adjbartime=not args.no_adjbartime,
          rightedge=not args.no_rightedge,
          takelate=not args.no_takelate,
      )
      
      if args.replay:
          cerebro.replaydata(dataname=data0, **rekwargs)
      
          if data1 is not None:
              cerebro.replaydata(dataname=data1, **rekwargs)
      
      elif args.resample:
          cerebro.resampledata(dataname=data0, **rekwargs)
      
          if data1 is not None:
              cerebro.resampledata(dataname=data1, **rekwargs)
      
      else:
          cerebro.adddata(data0)
          if data1 is not None:
              cerebro.adddata(data1)
      
      if args.valid is None:
          valid = None
      else:
          datetime.timedelta(seconds=args.valid)
      
      # Add the strategy
      cerebro.addstrategy(PairTradingStrategy,
                          period10=args.period10,
                          period20=args.period20,
                          stake=args.stake)
      
      
      # 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(
      formatter_class=argparse.ArgumentDefaultsHelpFormatter,
      description='Test Interactive Brokers integration')

      parser.add_argument('--exactbars', default=1, type=int,
                          required=False, action='store',
                          help='exactbars level, use 0/-1/-2 to enable plotting')
      
      parser.add_argument('--plot',
                          required=False, action='store_true',
                          help='Plot if possible')
      
      parser.add_argument('--stopafter', default=0, type=int,
                          required=False, action='store',
                          help='Stop after x lines of LIVE data')
      
      parser.add_argument('--usestore',
                          required=False, action='store_true',
                          help='Use the store pattern')
      
      parser.add_argument('--oldsync', action='store_true',
                          help='Use old data synchronization method')
      
      parser.add_argument('--runnext', action='store_true',
                          help='Use next by next instead of runonce')
      
      parser.add_argument('--notifyall',
                          required=False, action='store_true',
                          help='Notify all messages to strategy as store notifs')
      
      parser.add_argument('--nopreload', action='store_true',
                          help='Do not preload the data')
      
      parser.add_argument('--debug',
                          required=False, action='store_true',
                          help='Display all info received form IB')
      
      parser.add_argument('--period10', default=10, type=int,
                          help='Period to apply to the Simple Moving Average')
      
      parser.add_argument('--period20', default=20, type=int,
                          help='Period to apply to the Simple Moving Average')
      
      parser.add_argument('--host', default='127.0.0.1',
                          required=False, action='store',
                          help='Host for the Interactive Brokers TWS Connection')
      
      parser.add_argument('--qcheck', default=0.5, type=float,
                          required=False, action='store',
                          help=('Timeout for periodic '
                                'notification/resampling/replaying check'))
      
      parser.add_argument('--port', default=7496, type=int,
                          required=False, action='store',
                          help='Port for the Interactive Brokers TWS Connection')
      
      parser.add_argument('--clientId', default=None, type=int,
                          required=False, action='store',
                          help='Client Id to connect to TWS (default: random)')
      
      parser.add_argument('--no-timeoffset',
                          required=False, action='store_true',
                          help=('Do not Use TWS/System time offset for non '
                                'timestamped prices and to align resampling'))
      
      parser.add_argument('--reconnect', default=3, type=int,
                          required=False, action='store',
                          help='Number of recconnection attempts to TWS')
      
      parser.add_argument('--timeout', default=3.0, type=float,
                          required=False, action='store',
                          help='Timeout between reconnection attempts to TWS')
      
      parser.add_argument('--data0', default=None,
                          required=True, action='store',
                          help='data 0 into the system')
      
      parser.add_argument('--data1', default=None,
                          required=False, action='store',
                          help='data 1 into the system')
      
      parser.add_argument('--timezone', default=None,
                          required=False, action='store',
                          help='timezone to get time output into (pytz names)')
      
      parser.add_argument('--what', default=None,
                          required=False, action='store',
                          help='specific price type for historical requests')
      
      parser.add_argument('--no-backfill_start',
                          required=False, action='store_true',
                          help='Disable backfilling at the start')
      
      parser.add_argument('--latethrough',
                          required=False, action='store_true',
                          help=('if resampling replaying, adjusting time '
                                'and disabling time offset, let late samples '
                                'through'))
      
      parser.add_argument('--no-backfill',
                          required=False, action='store_true',
                          help='Disable backfilling after a disconnection')
      
      parser.add_argument('--rtbar', default=False,
                          required=False, action='store_true',
                          help='Use 5 seconds real time bar updates if possible')
      
      parser.add_argument('--commperc', default=0.005, type=float,
                          help='Percentage commission (0.005 is 0.5%%')
      
      parser.add_argument('--historical',
                          required=False, action='store_true',
                          help='do only historical download')
      
      parser.add_argument('--fromdate',
                          required=False, action='store',
                          help=('Starting date for historical download '
                                'with format: YYYY-MM-DD[THH:MM:SS]'))
      
      parser.add_argument('--smaperiod', default=5, type=int,
                          required=False, action='store',
                          help='Period to apply to the Simple Moving Average')
      
      pgroup = parser.add_mutually_exclusive_group(required=False)
      
      pgroup.add_argument('--replay',
                          required=False, action='store_true',
                          help='replay to chosen timeframe')
      
      pgroup.add_argument('--resample',
                          required=False, action='store_true',
                          help='resample to chosen timeframe')
      
      parser.add_argument('--timeframe', default=bt.TimeFrame.Names[0],
                          choices=bt.TimeFrame.Names,
                          required=False, action='store',
                          help='TimeFrame for Resample/Replay')
      
      parser.add_argument('--compression', default=1, type=int,
                          required=False, action='store',
                          help='Compression for Resample/Replay')
      
      parser.add_argument('--no-takelate',
                          required=False, action='store_true',
                          help=('resample/replay, do not accept late samples '
                                'in new bar if the data source let them through '
                                '(latethrough)'))
      
      parser.add_argument('--no-bar2edge',
                          required=False, action='store_true',
                          help='no bar2edge for resample/replay')
      
      parser.add_argument('--no-adjbartime',
                          required=False, action='store_true',
                          help='no adjbartime for resample/replay')
      
      parser.add_argument('--no-rightedge',
                          required=False, action='store_true',
                          help='no rightedge for resample/replay')
      
      parser.add_argument('--broker',
                          required=False, action='store_true',
                          help='Use IB as broker')
      
      parser.add_argument('--trade',
                          required=False, action='store_true',
                          help='Do Sample Buy/Sell operations')
      
      parser.add_argument('--donotsell',
                          required=False, action='store_true',
                          help='Do not sell after a buy')
      
      parser.add_argument('--exectype', default=bt.Order.ExecTypes[0],
                          choices=bt.Order.ExecTypes,
                          required=False, action='store',
                          help='Execution to Use when opening position')
      
      parser.add_argument('--stake', default=10, type=int,
                          required=False, action='store',
                          help='Stake to use in buy operations')
      
      parser.add_argument('--valid', default=None, type=int,
                          required=False, action='store',
                          help='Seconds to keep the order alive (0 means DAY)')
      
      parser.add_argument('--cancel', default=0, type=int,
                          required=False, action='store',
                          help=('Cancel a buy order after n bars in operation,'
                                ' to be combined with orders like Limit'))
      
      return parser.parse_args()
      

      if name == 'main':
      runstrategy()

      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        @YELNAr print self.dataX.get(size=self.p.periodXX) results and check what do you pass to pearsonr function. Maybe it is not what it takes.

        1 Reply Last reply Reply Quote 1
        • Y
          YELNAr last edited by

          @ab_trader said in ValueError: x and y must have length at least 2.:

          self.dataX.get(size=self.p.periodXX)

          In my laptop, print these types of error, while on another device it is work

          1 Reply Last reply Reply Quote 0
          • A
            ab_trader last edited by

            Which means that the problem can be in the configuration of the environment on your laptop.

            1 Reply Last reply Reply Quote 1
            • 1 / 1
            • First post
              Last post
            Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
            $(document).ready(function () { app.coldLoad(); }); }