PAIR TRADING IMPLEMENTATION WITH BACKTRADER
-
Hi guys ,
I'm new here.
I discovered BACKTRADER and I'm struggling with PAIR TRADING even if I found out a GitHub repository where we have the full access...but It doesn't work.
Anyway , I tried to apply the code to my .csv files but I get this error :
Traceback (most recent call last):
File "PairTradingStrategy.py", line 174, in <module>
cerebro.run()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1127, in run
runstrat = self.runstrategies(iterstrat)
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1212, in runstrategies
data.preload()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 688, in preload
while self.load():
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 479, in load
_loadret = self._load()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 710, in _load
return self._loadline(linetokens)
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feeds/yahoo.py", line 134, in _loadline
h = float(linetokens[next(i)])
IndexError: list index out of rangeand the code is as following :
"""
import backtrader as bt
import backtrader.analyzers as btanalyzers
import backtrader.indicators as btind
import datetime
"""
"""
class PairTradingStrategy(bt.Strategy):
params = dict(
period=10,
stake=10,
qty1=0,
qty2=0,
printout=True,
upper=2.1,
lower=-2.1,
up_medium=0.5,
low_medium=-0.5,
status=0,
portfolio_value=10000,
)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 __init__(self): # To control operation entries self.orderid = None self.qty1 = self.p.qty1 self.qty2 = self.p.qty2 self.upper_limit = self.p.upper self.lower_limit = self.p.lower self.up_medium = self.p.up_medium self.low_medium = self.p.low_medium self.status = self.p.status self.portfolio_value = self.p.portfolio_value # Signals performed with PD.OLS : self.transform = btind.OLS_TransformationN(self.data1, self.data2, period=self.p.period) self.zscore = self.transform.zscore # Checking signals built with StatsModel.API : # self.ols_transfo = btind.OLS_Transformation(self.data1, self.data2, # period=self.p.period, # plot=True)
""""
def next(self):
if self.orderid:
return # if an order is active, no new orders are allowedif self.p.printout: print('Self len:', len(self)) print('Data1 len:', len(self.data1)) print('Data2 len:', len(self.data2)) print('Data1 len == Data2 len:', len(self.data1) == len(self.data2)) print('Data1 dt:', self.data1.datetime.datetime()) print('Data2 dt:', self.data2.datetime.datetime()) print('status is', self.status) print('zscore is', self.zscore[0]) # Step 2: Check conditions for SHORT & place the order # Checking the condition for SHORT if (self.zscore[0] > self.upper_limit) and (self.status != 1): # Calculating the number of shares for each stock value = 0.5 * self.portfolio_value # Divide the cash equally x = int(value / (self.data1.close)) # Find the number of shares for Stock1 y = int(value / (self.data2.close)) # Find the number of shares for Stock2 print('x + self.qty1 is', x + self.qty1) print('y + self.qty2 is', y + self.qty2) # Placing the order self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1)) self.sell(data=self.data1, size=(x + self.qty1)) # Place an order for buying y + qty2 shares self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("KO", self.data2.close[0], y + self.qty2)) self.buy(data=self.data2, size=(y + self.qty2)) # Place an order for selling x + qty1 shares # Updating the counters with new value 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.status = 1 # The current status is "short the spread" # Step 3: Check conditions for LONG & place the order # Checking the condition for LONG elif (self.zscore[0] < self.lower_limit) and (self.status != 2): # Calculating the number of shares for each stock value = 0.5 * self.portfolio_value # Divide the cash equally x = int(value / (self.data1.close)) # Find the number of shares for Stock1 y = int(value / (self.data2.close)) # Find the number of shares for Stock2 print('x + self.qty1 is', x + self.qty1) print('y + self.qty2 is', y + self.qty2) # Place the order self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1)) self.buy(data=self.data1, size=(x + self.qty1)) # Place an order for buying x + qty1 shares self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data2.close[0], y + self.qty2)) self.sell(data=self.data2, size=(y + self.qty2)) # Place an order for selling y + qty2 shares # Updating the counters with new value 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.status = 2 # The current status is "long the spread" # Step 4: Check conditions for No Trade # If the z-score is within the two bounds, close all elif (self.zscore[0] < self.up_medium and self.zscore[0] > self.low_medium): self.log('CLOSE LONG %s, price = %.2f' % ("PEP", self.data1.close[0])) self.close(self.data1) self.log('CLOSE LONG %s, price = %.2f' % ("KO", self.data2.close[0])) self.close(self.data2)
"""
def stop(self): print('==================================================') print('Starting Value - %.2f' % self.broker.startingcash) print('Ending Value - %.2f' % self.broker.getvalue()) print('==================================================')
"""
"""
#Instantiate Cerebro engine
cerebro = bt.Cerebro()#Add data feed to Cerebro
data1 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AACQW.csv',
dtformat=('%Y.%m.%d'),
fromdate = datetime.datetime(2018,1,2),
todate = datetime.datetime(2021,1,15),
datetime=0,
time=-1,
high=-1,
low=-1,
open=-1,
close=1,
volume=-1,
openinterest=-1)
cerebro.adddata(data1)data2 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AAME.csv',
dtformat=('%Y.%m.%d'),
fromdate = datetime.datetime(2018,1,2),
todate = datetime.datetime(2021,1,15),
datetime=0,
time=-1,
high=-1,
low=-1,
open=-1,
close=1,
volume=-1,
openinterest=-1)
cerebro.adddata(data2)
"""
"""
#Add strategy to Cerebro
cerebro.addstrategy(PairTradingStrategy)"""
"""
if name == 'main':
# Run Cerebro Engine
start_portfolio_value = cerebro.broker.getvalue()cerebro.run() end_portfolio_value = cerebro.broker.getvalue() pnl = end_portfolio_value - start_portfolio_value print(f'Starting Portfolio Value: {start_portfolio_value:2f}') print(f'Final Portfolio Value: {end_portfolio_value:2f}') print(f'PnL: {pnl:.2f}')
#Run Cerebro Engine
cerebro.run()"""
"""Can anyone tell me please why I have an error and if the code is ok to make it run successfully ?
Thank you for your help!
-
@houba Can you do us a favour and repost your code as a whole between triple backslashes? See the instructions at the top of the page:
For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
-
Hi guys ,
I'm new here.
I discovered BACKTRADER and I'm struggling with PAIR TRADING even if I found out a GitHub repository where we have the full access...but It doesn't work.
Anyway , I tried to apply the code to my .csv files but I get this error :
Traceback (most recent call last):
File "PairTradingStrategy.py", line 174, in <module>
cerebro.run()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1127, in run
runstrat = self.runstrategies(iterstrat)
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1212, in runstrategies
data.preload()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 688, in preload
while self.load():
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 479, in load
_loadret = self._load()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 710, in _load
return self._loadline(linetokens)
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feeds/yahoo.py", line 134, in _loadline
h = float(linetokens[next(i)])
IndexError: list index out of rangeand the code is as following :
import backtrader as bt import backtrader.analyzers as btanalyzers import backtrader.indicators as btind import datetime class PairTradingStrategy(bt.Strategy): params = dict( period=10, stake=10, qty1=0, qty2=0, printout=True, upper=2.1, lower=-2.1, up_medium=0.5, low_medium=-0.5, status=0, portfolio_value=10000, ) 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 __init__(self): # To control operation entries self.orderid = None self.qty1 = self.p.qty1 self.qty2 = self.p.qty2 self.upper_limit = self.p.upper self.lower_limit = self.p.lower self.up_medium = self.p.up_medium self.low_medium = self.p.low_medium self.status = self.p.status self.portfolio_value = self.p.portfolio_value # Signals performed with PD.OLS : self.transform = btind.OLS_TransformationN(self.data1, self.data2, period=self.p.period) self.zscore = self.transform.zscore # Checking signals built with StatsModel.API : # self.ols_transfo = btind.OLS_Transformation(self.data1, self.data2, # period=self.p.period, # plot=True) def next(self): if self.orderid: return # if an order is active, no new orders are allowed if self.p.printout: print('Self len:', len(self)) print('Data1 len:', len(self.data1)) print('Data2 len:', len(self.data2)) print('Data1 len == Data2 len:', len(self.data1) == len(self.data2)) print('Data1 dt:', self.data1.datetime.datetime()) print('Data2 dt:', self.data2.datetime.datetime()) print('status is', self.status) print('zscore is', self.zscore[0]) # Step 2: Check conditions for SHORT & place the order # Checking the condition for SHORT if (self.zscore[0] > self.upper_limit) and (self.status != 1): # Calculating the number of shares for each stock value = 0.5 * self.portfolio_value # Divide the cash equally x = int(value / (self.data1.close)) # Find the number of shares for Stock1 y = int(value / (self.data2.close)) # Find the number of shares for Stock2 print('x + self.qty1 is', x + self.qty1) print('y + self.qty2 is', y + self.qty2) # Placing the order self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1)) self.sell(data=self.data1, size=(x + self.qty1)) # Place an order for buying y + qty2 shares self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("KO", self.data2.close[0], y + self.qty2)) self.buy(data=self.data2, size=(y + self.qty2)) # Place an order for selling x + qty1 shares # Updating the counters with new value 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.status = 1 # The current status is "short the spread" # Step 3: Check conditions for LONG & place the order # Checking the condition for LONG elif (self.zscore[0] < self.lower_limit) and (self.status != 2): # Calculating the number of shares for each stock value = 0.5 * self.portfolio_value # Divide the cash equally x = int(value / (self.data1.close)) # Find the number of shares for Stock1 y = int(value / (self.data2.close)) # Find the number of shares for Stock2 print('x + self.qty1 is', x + self.qty1) print('y + self.qty2 is', y + self.qty2) # Place the order self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1)) self.buy(data=self.data1, size=(x + self.qty1)) # Place an order for buying x + qty1 shares self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data2.close[0], y + self.qty2)) self.sell(data=self.data2, size=(y + self.qty2)) # Place an order for selling y + qty2 shares # Updating the counters with new value 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.status = 2 # The current status is "long the spread" # Step 4: Check conditions for No Trade # If the z-score is within the two bounds, close all elif (self.zscore[0] < self.up_medium and self.zscore[0] > self.low_medium): self.log('CLOSE LONG %s, price = %.2f' % ("PEP", self.data1.close[0])) self.close(self.data1) self.log('CLOSE LONG %s, price = %.2f' % ("KO", self.data2.close[0])) self.close(self.data2) def stop(self): print('==================================================') print('Starting Value - %.2f' % self.broker.startingcash) print('Ending Value - %.2f' % self.broker.getvalue()) print('==================================================') #Instantiate Cerebro engine cerebro = bt.Cerebro() #Add data feed to Cerebro data1 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AACQW.csv', dtformat=('%Y.%m.%d'), fromdate = datetime.datetime(2018,1,2), todate = datetime.datetime(2021,1,15), datetime=0, time=-1, high=-1, low=-1, open=-1, close=1, volume=-1, openinterest=-1) cerebro.adddata(data1) data2 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AAME.csv', dtformat=('%Y.%m.%d'), fromdate = datetime.datetime(2018,1,2), todate = datetime.datetime(2021,1,15), datetime=0, time=-1, high=-1, low=-1, open=-1, close=1, volume=-1, openinterest=-1) cerebro.adddata(data2) #Add strategy to Cerebro cerebro.addstrategy(PairTradingStrategy) if name == 'main': # Run Cerebro Engine start_portfolio_value = cerebro.broker.getvalue() cerebro.run() end_portfolio_value = cerebro.broker.getvalue() pnl = end_portfolio_value - start_portfolio_value print(f'Starting Portfolio Value: {start_portfolio_value:2f}') print(f'Final Portfolio Value: {end_portfolio_value:2f}') print(f'PnL: {pnl:.2f}') #Run Cerebro Engine cerebro.run()
Can anyone tell me please why I have an error and if the code is ok to make it run successfully ?
Thank you for your help!
-
@houba YahooFinanceCSVData implementation expect the OHLC columns to be present.
I guess your data file is not in Yahoo format and/or contains only close prices.
You may try to use GenericCSVData instead - it is much more forgiving and doesn't request all OHLC fields to be present.
-
@vladisld yes I found out already ; I should put the GenericCSVData and its arguments as you said)
Thks
from __future__ import (absolute_import, division, print_function, unicode_literals) import argparse import backtrader as bt import backtrader.analyzers as btanalyzers import backtrader.feeds as btfeeds import backtrader.indicators as btind import datetime import pandas as pd import matplotlib import pandas as pd import quantstats class PairsTradingStrategy(bt.Strategy) : params = dict( period = 10, stake = 10, qty1 = 0, qty2 = 0, printout = True, upper = 2.1, lower = -2.1, up_medium = 0.5, low_medium = -0.5, upper_level = 2.1, lower_level = -2.1, status = 0, portfolio_value=10000, ) 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 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 self.orderid = None def __init__(self): self.orderid = None self.qty1 = self.p.qty1 self.qty2 = self.p.qty2 self.upper_limit = self.p.upper self.lower_limit = self.p.lower self.up_medium = self.p.up_medium self.low_medium = self.p.low_medium self.status = self.p.status self.portfolio_value = self.p.portfolio_value self.transform = btind.OLS_TransformationN(self.data0,self.data1,period=self.p.period) self.zscore = self.transform.zscore def next(self) : if self.orderid : return if self.p.printout: print('Self len:', len(self)) print('Data0 len:', len(self.data0)) print('Data1 len:', len(self.data1)) print('Data0 len == Data1 len:', len(self.data0) == len(self.data1)) print('Data0 dt:', self.data0.datetime.datetime()) print('Data1 dt:', self.data1.datetime.datetime()) print('status is', self.status) print('zscore is', self.zscore[0]) # Step 2: Check conditions for SHORT & place the order # Checking the condition for SHORT if (self.zscore[0] > self.upper_limit) and (self.status != 1): # Calculating the number of shares for each stock value = 0.5 * self.portfolio_value # 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('x + self.qty1 is', x + self.qty1) print('y + self.qty2 is', y + self.qty2) # Placing the order self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data0.close[0], x + self.qty1)) self.sell(data=self.data0, size=(x + self.qty1)) # Place an order for buying y + qty2 shares self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data1.close[0], y + self.qty2)) self.buy(data=self.data1, size=(y + self.qty2)) # Place an order for selling x + qty1 shares # Updating the counters with new value 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.status = 1 # The current status is "short the spread" # Step 3: Check conditions for LONG & place the order # Checking the condition for LONG elif (self.zscore[0] < self.lower_limit) and (self.status != 2): # Calculating the number of shares for each stock value = 0.5 * self.portfolio_value # 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('x + self.qty1 is', x + self.qty1) print('y + self.qty2 is', y + self.qty2) # Place the order self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data0.close[0], x + self.qty1)) self.buy(data=self.data0, size=(x + self.qty1)) # Place an order for buying x + qty1 shares self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data1.close[0], y + self.qty2)) self.sell(data=self.data1, size=(y + self.qty2)) # Place an order for selling y + qty2 shares # Updating the counters with new value 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.status = 2 # The current status is "long the spread" # Step 4: Check conditions for No Trade # If the z-score is within the two bounds, close all elif (self.zscore[0] < self.up_medium and self.zscore[0] > self.low_medium): self.log('CLOSE LONG %s, price = %.2f' % ("AACQW", self.data0.close[0])) self.close(self.data0) self.log('CLOSE LONG %s, price = %.2f' % ("AAME", self.data1.close[0])) self.close(self.data1) def stop(self): print('==================================================') print('Starting Value - %.2f' % self.broker.startingcash) print('Ending Value - %.2f' % self.broker.getvalue()) print('==================================================') def parse_args(): parser = argparse.ArgumentParser(description='MultiData Strategy') parser.add_argument('--data0', '-d0', default='/Users/bibani/Desktop/AACQW.csv', help='1st data into the system') parser.add_argument('--data1', '-d1', default='/Users/bibani/Desktop/AAME.csv', help='2nd data into the system') parser.add_argument('--fromdate', '-f', default='2018-01-02', help='Starting date in YYYY-MM-DD format') parser.add_argument('--todate', '-t', default='2021-01-15', help='Starting date in YYYY-MM-DD format') parser.add_argument('--period', default=10, type=int, help='Period to apply to the Simple Moving Average') parser.add_argument('--cash', default=100000, type=int, help='Starting Cash') parser.add_argument('--runnext', action='store_true', help='Use next by next instead of runonce') parser.add_argument('--nopreload', action='store_true', help='Do not preload the data') parser.add_argument('--oldsync', action='store_true', help='Use old data synchronization method') parser.add_argument('--commperc', default=0.005, type=float, help='Percentage commission (0.005 is 0.5%%') parser.add_argument('--stake', default=10, type=int, help='Stake to apply in each operation') parser.add_argument('--plot', '-p', default=True, action='store_true', help='Plot the read data') parser.add_argument('--numfigs', '-n', default=1, help='Plot using numfigs figures') return parser.parse_args() def runstrategy(): args = parse_args() # Create a cerebro cerebro = bt.Cerebro() # Get the dates from the args fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d') todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d') # Create the 1st data data0 = btfeeds.GenericCSVData( dataname=args.data0, dtformat = ('%Y-%m-%d'), fromdate=fromdate, todate=todate, datetime=0, high=-1, low=-1, open=-1, close=1, volume=-1, openinterest=-1 ) # Add the 1st data to cerebro cerebro.adddata(data0) # Create the 2nd data data1 = btfeeds.GenericCSVData( dataname=args.data1, dtformat = ('%Y-%m-%d'), fromdate=fromdate, todate=todate, datetime=0, high=-1, low=-1, open=-1, close=1, volume=-1, openinterest=-1 ) # Add the 2nd data to cerebro cerebro.adddata(data1) # Add the strategy cerebro.addstrategy(PairsTradingStrategy, period=args.period, stake=args.stake) cerebro.broker.setcash(args.cash) # Add the commission - only stocks like a for each operation cerebro.broker.setcommission(commission=args.commperc) # And run it results = cerebro.run(runonce=not args.runnext, preload=not args.nopreload, oldsync=args.oldsync) cerebro.broker.getvalue() cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='SharpeRatio') cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW') end_portfolio_value = cerebro.broker.getvalue() #print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) #print('SR:', cerebro.analyzers.SharpeRatio.get_analysis()) #print('DW:', cerebro.analyzers.DW.get_analysis()) # Plot if requested if args.plot: cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False) if __name__ == '__main__': runstrategy()
why am I getting this error :
<IPython.core.display.Javascript object>
<IPython.core.display.HTML object>
Traceback (most recent call last):
File "Test_Iheb.py", line 275, in <module>
runstrategy()
File "Test_Iheb.py", line 272, in runstrategy
cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False)
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 996, in plot
plotter.show()
File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/plot/plot.py", line 817, in show
self.mpyplot.show()
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/pyplot.py", line 269, in show
return _show(*args, **kw)
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 261, in show
manager.show()
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 90, in show
self._create_comm()
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 122, in _create_comm
self.add_web_socket(comm)
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 432, in add_web_socket
self.resize(w, h)
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 418, in resize
size=(w / self.canvas._dpi_ratio, h / self.canvas._dpi_ratio))
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 489, in _send_event
s.send_json(payload)
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 199, in send_json
self.comm.send({'data': json.dumps(content)})
File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 123, in send
data=data, metadata=metadata, buffers=buffers,
File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 66, in _publish_msg
self.kernel.session.send(self.kernel.iopub_socket, msg_type,
AttributeError: 'NoneType' object has no attribute 'session'
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/_pylab_helpers.py", line 73, in destroy_all
manager.destroy()
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 126, in destroy
self._send_event('close')
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 489, in _send_event
s.send_json(payload)
File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 199, in send_json
self.comm.send({'data': json.dumps(content)})
File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 123, in send
data=data, metadata=metadata, buffers=buffers,
File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 66, in _publish_msg
self.kernel.session.send(self.kernel.iopub_socket, msg_type,
AttributeError: 'NoneType' object has no attribute 'session' -
@houba I'm not using IPython myself but probably the following post may help: https://community.backtrader.com/topic/1911/cerebro-plot-does-not-work-with-anaconda-ipython?_=1614109874231
-
@vladisld thanks again :)
-
@vladisld Actually No , the problem is not in the "cerebro.plot" ....If any one has any idea please do not hesitate
-
@vladisld Actually , YES , it helps but not sufficient :)
I have as an ending value : NaN
Also , I don't have any signals on the positions taken ....
BackTrader_Test.png image url)