For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See:

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

  • Print error "File "C:\Users\user\Anaconda3\envs\BackTrading\lib\site-packages\scipy\stats\", 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,
      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(

    def log(self, txt, dt=None):
        if self.p.printout:
            dt = dt or[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)
                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 =
        # # 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),
        c20_basket1, p = scipy.stats.pearsonr(self.data0.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))
  , 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))
  , 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('Starting Value - %.2f' %
        print('Ending   Value - %.2f' %

    def runstrategy():
    args = parse_args()

    # Create a cerebro
    cerebro = bt.Cerebro()
    storekwargs = dict(, 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.usestore:
            broker = ibstore.getbroker()
            broker = bt.brokers.IBBroker(**storekwargs)
    timeframe = bt.TimeFrame.TFrame(args.timeframe)
    if args.resample or args.replay:
        datatf = bt.TimeFrame.Ticks
        datacomp = 1
        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,
        backfill_start=not args.no_backfill_start,
        backfill=not args.no_backfill,
    if not args.usestore and not   # 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)
        if data1 is not None:
    if args.valid is None:
        valid = None
    # Add the strategy
    # Add the commission - only stocks like a for each operation
    # And run it
    # Plot if requested
    if args.plot:
        cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False)

    def parse_args():
    parser = argparse.ArgumentParser(
    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')
                        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')
                        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')
                        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')
                        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='',
                        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)')
                        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')
                        required=False, action='store_true',
                        help='Disable backfilling at the start')
                        required=False, action='store_true',
                        help=('if resampling replaying, adjusting time '
                              'and disabling time offset, let late samples '
                        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%%')
                        required=False, action='store_true',
                        help='do only historical download')
                        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)
                        required=False, action='store_true',
                        help='replay to chosen timeframe')
                        required=False, action='store_true',
                        help='resample to chosen timeframe')
    parser.add_argument('--timeframe', default=bt.TimeFrame.Names[0],
                        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')
                        required=False, action='store_true',
                        help=('resample/replay, do not accept late samples '
                              'in new bar if the data source let them through '
                        required=False, action='store_true',
                        help='no bar2edge for resample/replay')
                        required=False, action='store_true',
                        help='no adjbartime for resample/replay')
                        required=False, action='store_true',
                        help='no rightedge for resample/replay')
                        required=False, action='store_true',
                        help='Use IB as broker')
                        required=False, action='store_true',
                        help='Do Sample Buy/Sell operations')
                        required=False, action='store_true',
                        help='Do not sell after a buy')
    parser.add_argument('--exectype', default=bt.Order.ExecTypes[0],
                        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':

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

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


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

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

Log in to reply