ValueError: x and y must have length at least 2.
-
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() -
@YELNAr print
self.dataX.get(size=self.p.periodXX)
results and check what do you pass topearsonr
function. Maybe it is not what it takes. -
@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
-
Which means that the problem can be in the configuration of the environment on your laptop.