Is there a way to delete this topic? I was able to resolve the problem.

Best posts made by Adham Suliman
-
RE: Why won't order.Accept? Is it because I need volume?
-
Market buy orders are Submitted, but not Accepted or Executed
I am currently backtesting a strategy where backtrader acts normally up until about a third of the way through the entire data set. From that point on, backtrader seems to only be capable of creating a buy order and submitting it, but not accepting or executing the order. I have three attachments associated with this post. The first is the strategy, then the second is the image where we can see that backtrader is incapable of accepting/executing an order, and finally the log output. Does anyone know as to why my orders are not being accepted/executed? Thanks!
Please note, not all objects are defined in the provided script.
Code:
class EmaCross(bt.Strategy): params = {('order_percentage', .95)} plotlines = dict( ema_s=dict(_name = 'ema_s', ls='--', color='yellow'), # use same color as prev line (dcm) ema_l=dict(_name = 'ema_l', ls='--', color='blue')) # use same color as prev line (dch) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.dataopen = self.datas[0].open self.dataclose = self.datas[0].close self.datahigh = self.datas[0].high self.datalow = self.datas[0].low # Bring in moving averages self.myind = color_ind() # Define average true range self.atr = bt.indicators.ATR(self.datas[0], period =14) # Define self order self.order = None self.trail_stop = None self.cross_down = None def notify_order(self, order): #Cancel stop if cross initiated if (self.cross_down and self.trail_stop): self.cancel(self.trail_stop) # Check the order status. # If it is submitted/accepted, leave the fucntion if order.status in [order.Submitted, order.Accepted]: if order.isbuy(): self.log(f"Buy Submitted at {order}") return if order.status in [order.Completed]: if order.isbuy(): # Keep track of executred price and stop loss self.log(f"Buy Executed at {order.executed.price}") if order.issell(): # Keep track of sell price self.log(f"Sell Executed at {order.executed.price} and order {order}") self.cancel(self.cross_down) self.cancel(self.trail_stop) print(f'position: \n {self.position} and order: \n {order}') if order.status == order.Canceled: #self.log(f'Order canceled at {self.dataclose[0]} and order is \n{order}') return # Sentinel to None: new orders allowed self.order = None self.trail_stop = None self.cross_down = None def next(self): if self.order: return # if there is no current postion if self.position.size == 0: self.cancel(self.cross_down) if ( self.myind.ema_s[0] > self.myind.ema_l[0] and self.myind.ema_s[-1] < self.myind.ema_l[-1] ): self.size = 1 self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy(size = self.size) elif self.position.size > 0: if (self.trail_stop is None and self.cross_down is None and sell_type in ['atr_sell','atr_cross_sell']): # cancel any prior cross_down self.cancel(self.cross_down) # sell on trailing stop self.trail_stop = self.close(exectype=bt.Order.StopTrail, trailamount = atr_stop * self.atr[0], size = self.position.size, ref = '999') elif (self.myind.ema_s[0] < self.myind.ema_l[0] and (self.myind.ema_s[-1] > self.myind.ema_l[-1] or self.myind.ema_s[-2] > self.myind.ema_l[-2]) and (self.cross_down is None) and sell_type in ['cross_sell','atr_cross_sell']): # cancel trailing stop self.cancel(self.trail_stop) # sell on the cros down self.cross_down = self.close() if f in ['30min','15min','hour','4hour']: if f == '30min': compression = 30 elif f == '15min': compression = 15 elif f == 'hour': compression = 60 else: compression = 240 data0 = pd.read_csv(f'data/{c}/{f}/{d}.csv' ) #index_col=[0], parse_dates=[0] data0['time'] = data0.reset_index().time.apply(lambda x: datetime.strptime(x,'%m/%d/%Y %H:%M')) data0.set_index('time',inplace = True) data = bt.feeds.PandasData(dataname = data0, timeframe = bt.TimeFrame.Minutes, compression = compression) else: data0 = pd.read_csv(f'data/{c}/{f}/{d}.csv',index_col=[0], parse_dates=[0] ) start = pd.to_datetime(data0.index.max()) - pd.offsets.DateOffset(months=3) - timedelta(days = 10) data0 = data0[data0.index>=start] data = bt.feeds.PandasData(dataname = data0, timeframe = bt.TimeFrame.Days) b = Bokeh(style='bar', plot_mode='multi', scheme=Tradimo(), bar_up = 'green') cerebro = bt.Cerebro() if contract == 'RTY': cerebro.broker.setcommission(commission = .85, mult = 50, stocklike=False, margin = 10000) elif contract == 'ES': cerebro.broker.setcommission(commission = .85, mult = 12.5, stocklike=False, margin = 15000) elif contract == 'NQ': cerebro.broker.setcommission(commission = .85, mult = 20, stocklike=False, margin = 22000) elif contract == 'NG': cerebro.broker.setcommission(commission = .85, mult = 10, stocklike=False, margin = 10000) elif contract == 'CL': cerebro.broker.setcommission(commission = .85, mult = 10, stocklike=False, margin = 10000) cerebro.addstrategy(EmaCross) cerebro.broker.setcash(50000.0) cerebro.adddata(data) cerebro.addwriter(bt.WriterFile, csv = True, out='data.csv') #cerebro.broker.set_coc(True) cerebro.run() cerebro.plot(b, iplot = False)
Image:
Output
2008-12-15T05:00:00, Buy Executed at 1273.75 2008-12-22T15:15:00, Sell Executed at 1224.11104544575 and order Ref: 20320 OrdType: 1 OrdType: Sell Status: 4 Status: Completed Size: -1 Price: None Price Limit: None TrailAmount: 69.13895455424985 TrailPercent: None ExecType: 5 ExecType: StopTrail CommInfo: <backtrader.comminfo.CommInfoBase object at 0x0000024D2EFEA748> End of Session: 733391.9999999999 Info: AutoOrderedDict([('ref', '999')]) Broker: None Alive: False 2008-12-30T11:30:00, BUY CREATE, 1252.50 2008-12-30T15:15:00, Buy Submitted at Ref: 20321 OrdType: 0 OrdType: Buy Status: 1 Status: Submitted Size: 1 Price: None Price Limit: None TrailAmount: None TrailPercent: None ExecType: 0 ExecType: Market CommInfo: None End of Session: 733406.9999999999 Info: AutoOrderedDict() Broker: None Alive: True 2008-12-30T15:15:00, BUY CREATE, 1259.75 2008-12-30T19:30:00, Buy Submitted at Ref: 20322 OrdType: 0 OrdType: Buy Status: 1 Status: Submitted Size: 1 Price: None Price Limit: None TrailAmount: None TrailPercent: None ExecType: 0 ExecType: Market CommInfo: None End of Session: 733406.9999999999 Info: AutoOrderedDict() Broker: None Alive: True
Latest posts made by Adham Suliman
-
RE: Multi Assets on IB Not Responding
For anyone looking to use this in the future, in the next method, I was trying to access a dictionary using
inds[d].field[0]
. The proper syntax to access a dictionary isinds[d]['field'][0]
. I also lowered my qcheck to .05 as @vladisld suggested. If someone has a link as to how to handle multiple orders with multiple data feeds, I would highly appreciate it if you posted the link below.Thanks
-
RE: Multi Assets on IB Not Responding
You're correct. After reading the documentation in more detail, there is no need to resample the data. I am now using cerebro.adddata(). I'm still getting the same output as before where a connection is made, but bt isn't performing any trades. I've cleaned up my main file, and have written it below.
Python code to add data feeds and connect to IB
# import modules import sys, argparse, os from datetime import datetime import backtrader as bt import backtrader.stores.ibstore as ibstore from strategy.long_copy import EmaCross_long def run(): cerebro = bt.Cerebro(stdstats=False) ibstore = bt.stores.IBStore(host='127.0.0.1', port=4002, clientId=0) # Adding two data feeds contracts = ['NQ-202103-GLOBEX-USD','RTY-202103-GLOBEX-USD'] # c_name = ['NQ','RTY'] for d,c in zip(contracts,c_name): data = ibstore.getdata(dataname=d, timeframe=bt.TimeFrame.Seconds, compression=5, rtbar=True, # use RealTime 5 seconds bars historical = False, qcheck=100, # timeout in seconds (float) to check for events latethrough=False) cerebro.adddata(data, name=c) cerebro.broker = ibstore.getbroker() cerebro.addstrategy(EmaCross_long) cerebro.run() if __name__ == '__main__': run()
Are there any places you would suggest setting breakpoints within the bt.strategy script that would help us figure out why bt isn't placing any trades?
Your contributions to the community are highly appreciated @vladisld. I've benefited immensely from your commentary on this forum, and I can't thank you enough!
-
RE: Multi Assets on IB Not Responding
I realized some of the code within the bt.strategy script wasn't correctly calling the datas feed within next(). I updated the script, but I'm still having the respective issues above. Below is the updated script for bt.strategy.
Python code for bt.strategy
import backtrader as bt from datetime import datetime, timedelta import time import math class EmaCross_long(bt.Strategy): params = {('order_percentage', .95)} def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.orderid = list() self.inds = dict() for i, d in enumerate(self.datas): self.inds[d] = dict() self.inds[d]['dataopen'] = d.open self.inds[d]['dataclose'] = d.close self.inds[d]['datahigh'] = d.high self.inds[d]['datalow'] = d.low # Define average true range self.inds[d]['atr'] = bt.indicators.ATR(d, period =14) self.inds[d]['ema_s'] = bt.indicators.EMA(d,period=6,plotname='ema_s (6)') self.inds[d]['ema_l'] = bt.indicators.EMA(d, period=17, plotname='ema_l (17)') # Define self order self.order = None self.trail_stop = None self.cross_down = None self.sell_type = 'atr_cross_sell' def notify_store(self, msg, *args, **kwargs): print(f'message: {msg}') error = getattr(msg,'errorCode',False) if error: print(error) def notify_order(self, order): # https://www.backtrader.com/docu/order-creation-execution/order-creation-execution/ # Check the order status. print('{}: Order ref: {} / Type {} / Status {}'.format( self.data.datetime.datetime(0), order.ref, 'Buy' * order.isbuy() or 'Sell', order.getstatusname())) # If it is submitted/accepted, leave the fucntion if order.status in [order.Submitted, order.Accepted]: #self.log(f"Order submitted/accepted but not complete") return if order.status in [order.Completed]: if order.isbuy(): # Keep track of executred price and stop loss self.log(f"Buy Executed at {order.executed.price}") elif order.issell(): # Keep track of sell price self.log(f"Sell Executed at {order.executed.price} and order {order}") #print(f'position: \n {self.position} and order: \n {order}') self.order = None self.trail_stop = None self.cross_down = None if order.status in [order.Canceled, order.Margin, order.Rejected]: self.log(f"Order Rejected: {order.Rejected}") return if order.status == order.Canceled: self.log(f'Order Canceled {order.Canceled}') return def next(self): if self.order: # An order is pending ... nothing can be done return # if there is no current postion for i, d in enumerate(self.datas): if self.getposition(d).size <= 0: if (self.inds[d].dataclose[0] > self.inds[d].ema_s[0] and self.inds[d].ema_s[0] > self.inds[d].ema_l[0] and (self.inds[d].ema_s[-1] < self.inds[d].ema_l[-1] or self.inds[d].ema_s[-2] < self.inds[d].ema_l[-2])): # amount to invest #amount_to_invest = self.params.order_percentage * self.broker.cash #self.size = math.floor(amount_to_invest/self.dataclose) self.size = 1 self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy(size = self.size, data = d) #elif self.getposition(d) > 0: # if (self.trail_stop is None and self.cross_down is None and self.sell_type in ['atr_sell','atr_cross_sell']): # # cancel any prior cross_down # try: # self.cancel(self.cross_down) # except: # pass # # sell on trailing stop # self.trail_stop = self.close(data = d, # exectype=bt.Order.StopTrail, # trailamount = 3 * self.atr[0], # size = self.getposition(d), # ref = '999') # #valid = datetime.now() + timedelta(hours = 12)) elif (self.getposition(d) > 0 and self.inds[d].ema_s[0] < self.inds[d].ema_l[0] and (self.inds[d].ema_s[-1] > self.inds[d].ema_l[-1] or self.inds[d].ema_s[-2] > self.inds[d].ema_l[-2])): # sell on the cros down self.cross_down = self.close(data = d)
-
Multi Assets on IB Not Responding
Hello,
I'm having trouble executing one strategy on two live data feeds on Interactive Brokers. It seems like the connection is being made, but the strategy doesn't seem to be making any trades. When I reduce the data feeds to one data feed, the program works.
The first set of code is used to make the connection to interactive brokers. The second section of code is the strategy. Finally, the third is the output from python. I can see that the connection is being made, but again, no trades are being made. Any help would be highly appreciated.
Python code to add data feeds and connect to IB
import sys, argparse, os from datetime import datetime import backtrader as bt import backtrader.stores.ibstore as ibstore from strategy.long_copy import EmaCross_long def run(): cerebro = bt.Cerebro(stdstats=False) ibstore = bt.stores.IBStore(host='127.0.0.1', port=4002, clientId=0) stockkwargs = dict( timeframe=bt.TimeFrame.Seconds, rtbar=True, # use RealTime 5 seconds bars historical = False, qcheck=100, # timeout in seconds (float) to check for events latethrough=False) # tradename=None, # use a different asset as order target # fromdate = datetime.today()) contracts = ['NQ-202103-GLOBEX-USD','RTY-202103-GLOBEX-USD'] # c_name = ['NQ','RTY'] for d,c in zip(contracts,c_name): data = ibstore.getdata(dataname=d,**stockkwargs) cerebro.resampledata(data, name=c, timeframe=bt.TimeFrame.Seconds, compression=5) cerebro.broker = ibstore.getbroker() cerebro.addstrategy(EmaCross_long) cerebro.run() if __name__ == '__main__': run()
Python code for bt.strategy
import pandas as pd import backtrader as bt from datetime import datetime, timedelta import time import math import sqlalchemy as db class EmaCross_long(bt.Strategy): params = {('order_percentage', .95)} def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.orderid = list() self.inds = dict() for i,d in enumerate(self.datas): self.inds[d] = dict() self.inds[d]['dataopen'] = d.open self.inds[d]['dataclose'] = d.close self.inds[d]['datahigh'] = d.high self.inds[d]['datalow'] = d.low # Define average true range self.inds[d]['atr'] = bt.indicators.ATR(d, period =14) self.inds[d]['ema_s'] = bt.indicators.EMA(d,period=6,plotname='ema_s (6)') self.inds[d]['ema_l'] = bt.indicators.EMA(d, period=17, plotname='ema_l (17)') # Define self order self.order = None self.trail_stop = None self.cross_down = None self.sell_type = 'atr_cross_sell' def notify_store(self, msg, *args, **kwargs): print(f'message: {msg}') error = getattr(msg,'errorCode',False) if error: print(error) def notify_order(self, order): # https://www.backtrader.com/docu/order-creation-execution/order-creation-execution/ # Check the order status. print('{}: Order ref: {} / Type {} / Status {}'.format( self.data.datetime.datetime(0), order.ref, 'Buy' * order.isbuy() or 'Sell', order.getstatusname())) # If it is submitted/accepted, leave the fucntion if order.status in [order.Submitted, order.Accepted]: #self.log(f"Order submitted/accepted but not complete") return if order.status in [order.Completed]: if order.isbuy(): # Keep track of executred price and stop loss self.log(f"Buy Executed at {order.executed.price}") elif order.issell(): # Keep track of sell price self.log(f"Sell Executed at {order.executed.price} and order {order}") #print(f'position: \n {self.position} and order: \n {order}') self.order = None self.trail_stop = None self.cross_down = None if order.status in [order.Canceled, order.Margin, order.Rejected]: self.log(f"Order Rejected: {order.Rejected}") return if order.status == order.Canceled: self.log(f'Order Canceled {order.Canceled}') return def next(self): if self.order: # An order is pending ... nothing can be done return # if there is no current postion for i, d in enumerate(self.datas): if self.getposition(d).size <= 0: try: self.cancel(self.cross_down) except: pass if (self.inds[d].dataclose[0] > self.inds[d].ema_s[0] and self.inds[d].ema_s[0] > self.inds[d].ema_l[0] and (self.inds[d].ema_s[-1] < self.ema_l[-1] or self.inds[d].ema_s[-2] < self.inds[d].ema_l[-2])): # amount to invest #amount_to_invest = self.params.order_percentage * self.broker.cash #self.size = math.floor(amount_to_invest/self.dataclose) self.size = 1 self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy(size = self.size, data = d) #elif self.getposition(d) > 0: # if (self.trail_stop is None and self.cross_down is None and self.sell_type in ['atr_sell','atr_cross_sell']): # # cancel any prior cross_down # try: # self.cancel(self.cross_down) # except: # pass # # sell on trailing stop # self.trail_stop = self.close(data = d, # exectype=bt.Order.StopTrail, # trailamount = 3 * self.atr[0], # size = self.getposition(d), # ref = '999') # #valid = datetime.now() + timedelta(hours = 12)) elif (self.getposition(d) > 0 and self.ema_s[0] < self.ema_l[0] and (self.inds[d].ema_s[-1] > self.inds[d].ema_l[-1] or self.inds[d].ema_s[-2] > self.inds[d].ema_l[-2])): # cancel trailing stop self.cancel(self.trail_stop) # sell on the cros down self.cross_down = self.close(data = d)
IB is connecting, but bt isn't performing any trades.
Server Version: 76 TWS Time at connection:20210113 11:47:50 EST message: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfuture.nj> 2104 message: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm.nj> 2104 message: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfuture> 2104 message: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:cashfarm> 2104 message: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm> 2104 message: <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:euhmds> 2106 message: <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:fundfarm> 2106 message: <error id=-1, errorCode=2106, errorMsg=HMDS data farm connection is OK:ushmds> 2106 message: <error id=-1, errorCode=2158, errorMsg=Sec-def data farm connection is OK:secdefil> 2158
-
RE: Market buy orders are Submitted, but not Accepted or Executed
Hello Jonny,
I don't think that is the case as the only point a buy market order can be cancelled is within the sentinel. The code within sentinel shouldn't execute in the current script because backtrader should be exiting the
notify_order
function with the code below. Please let me know if my reasoning is flawed here.if order.status in [order.Submitted, order.Accepted]: if order.isbuy(): self.log(f"Buy Submitted at {order}") return
-
Market buy orders are Submitted, but not Accepted or Executed
I am currently backtesting a strategy where backtrader acts normally up until about a third of the way through the entire data set. From that point on, backtrader seems to only be capable of creating a buy order and submitting it, but not accepting or executing the order. I have three attachments associated with this post. The first is the strategy, then the second is the image where we can see that backtrader is incapable of accepting/executing an order, and finally the log output. Does anyone know as to why my orders are not being accepted/executed? Thanks!
Please note, not all objects are defined in the provided script.
Code:
class EmaCross(bt.Strategy): params = {('order_percentage', .95)} plotlines = dict( ema_s=dict(_name = 'ema_s', ls='--', color='yellow'), # use same color as prev line (dcm) ema_l=dict(_name = 'ema_l', ls='--', color='blue')) # use same color as prev line (dch) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.datetime(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.dataopen = self.datas[0].open self.dataclose = self.datas[0].close self.datahigh = self.datas[0].high self.datalow = self.datas[0].low # Bring in moving averages self.myind = color_ind() # Define average true range self.atr = bt.indicators.ATR(self.datas[0], period =14) # Define self order self.order = None self.trail_stop = None self.cross_down = None def notify_order(self, order): #Cancel stop if cross initiated if (self.cross_down and self.trail_stop): self.cancel(self.trail_stop) # Check the order status. # If it is submitted/accepted, leave the fucntion if order.status in [order.Submitted, order.Accepted]: if order.isbuy(): self.log(f"Buy Submitted at {order}") return if order.status in [order.Completed]: if order.isbuy(): # Keep track of executred price and stop loss self.log(f"Buy Executed at {order.executed.price}") if order.issell(): # Keep track of sell price self.log(f"Sell Executed at {order.executed.price} and order {order}") self.cancel(self.cross_down) self.cancel(self.trail_stop) print(f'position: \n {self.position} and order: \n {order}') if order.status == order.Canceled: #self.log(f'Order canceled at {self.dataclose[0]} and order is \n{order}') return # Sentinel to None: new orders allowed self.order = None self.trail_stop = None self.cross_down = None def next(self): if self.order: return # if there is no current postion if self.position.size == 0: self.cancel(self.cross_down) if ( self.myind.ema_s[0] > self.myind.ema_l[0] and self.myind.ema_s[-1] < self.myind.ema_l[-1] ): self.size = 1 self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy(size = self.size) elif self.position.size > 0: if (self.trail_stop is None and self.cross_down is None and sell_type in ['atr_sell','atr_cross_sell']): # cancel any prior cross_down self.cancel(self.cross_down) # sell on trailing stop self.trail_stop = self.close(exectype=bt.Order.StopTrail, trailamount = atr_stop * self.atr[0], size = self.position.size, ref = '999') elif (self.myind.ema_s[0] < self.myind.ema_l[0] and (self.myind.ema_s[-1] > self.myind.ema_l[-1] or self.myind.ema_s[-2] > self.myind.ema_l[-2]) and (self.cross_down is None) and sell_type in ['cross_sell','atr_cross_sell']): # cancel trailing stop self.cancel(self.trail_stop) # sell on the cros down self.cross_down = self.close() if f in ['30min','15min','hour','4hour']: if f == '30min': compression = 30 elif f == '15min': compression = 15 elif f == 'hour': compression = 60 else: compression = 240 data0 = pd.read_csv(f'data/{c}/{f}/{d}.csv' ) #index_col=[0], parse_dates=[0] data0['time'] = data0.reset_index().time.apply(lambda x: datetime.strptime(x,'%m/%d/%Y %H:%M')) data0.set_index('time',inplace = True) data = bt.feeds.PandasData(dataname = data0, timeframe = bt.TimeFrame.Minutes, compression = compression) else: data0 = pd.read_csv(f'data/{c}/{f}/{d}.csv',index_col=[0], parse_dates=[0] ) start = pd.to_datetime(data0.index.max()) - pd.offsets.DateOffset(months=3) - timedelta(days = 10) data0 = data0[data0.index>=start] data = bt.feeds.PandasData(dataname = data0, timeframe = bt.TimeFrame.Days) b = Bokeh(style='bar', plot_mode='multi', scheme=Tradimo(), bar_up = 'green') cerebro = bt.Cerebro() if contract == 'RTY': cerebro.broker.setcommission(commission = .85, mult = 50, stocklike=False, margin = 10000) elif contract == 'ES': cerebro.broker.setcommission(commission = .85, mult = 12.5, stocklike=False, margin = 15000) elif contract == 'NQ': cerebro.broker.setcommission(commission = .85, mult = 20, stocklike=False, margin = 22000) elif contract == 'NG': cerebro.broker.setcommission(commission = .85, mult = 10, stocklike=False, margin = 10000) elif contract == 'CL': cerebro.broker.setcommission(commission = .85, mult = 10, stocklike=False, margin = 10000) cerebro.addstrategy(EmaCross) cerebro.broker.setcash(50000.0) cerebro.adddata(data) cerebro.addwriter(bt.WriterFile, csv = True, out='data.csv') #cerebro.broker.set_coc(True) cerebro.run() cerebro.plot(b, iplot = False)
Image:
Output
2008-12-15T05:00:00, Buy Executed at 1273.75 2008-12-22T15:15:00, Sell Executed at 1224.11104544575 and order Ref: 20320 OrdType: 1 OrdType: Sell Status: 4 Status: Completed Size: -1 Price: None Price Limit: None TrailAmount: 69.13895455424985 TrailPercent: None ExecType: 5 ExecType: StopTrail CommInfo: <backtrader.comminfo.CommInfoBase object at 0x0000024D2EFEA748> End of Session: 733391.9999999999 Info: AutoOrderedDict([('ref', '999')]) Broker: None Alive: False 2008-12-30T11:30:00, BUY CREATE, 1252.50 2008-12-30T15:15:00, Buy Submitted at Ref: 20321 OrdType: 0 OrdType: Buy Status: 1 Status: Submitted Size: 1 Price: None Price Limit: None TrailAmount: None TrailPercent: None ExecType: 0 ExecType: Market CommInfo: None End of Session: 733406.9999999999 Info: AutoOrderedDict() Broker: None Alive: True 2008-12-30T15:15:00, BUY CREATE, 1259.75 2008-12-30T19:30:00, Buy Submitted at Ref: 20322 OrdType: 0 OrdType: Buy Status: 1 Status: Submitted Size: 1 Price: None Price Limit: None TrailAmount: None TrailPercent: None ExecType: 0 ExecType: Market CommInfo: None End of Session: 733406.9999999999 Info: AutoOrderedDict() Broker: None Alive: True
-
Submitted StopTrail is dead but then somehow Completed?
Hello,
I somehow have a bt.Order.StopTrail that refuses to be canceled. I am working on a shorting strategy where I buy a short based on some indicators. The position will only be closed when a trailing stop is satisfied or self.cross_up is satisfied.Below is the code for notify_order(). I have tried in several places within the method to cancel the trailing stop (self.trail_stop')
def notify_order(self, order): # https://www.backtrader.com/docu/order-creation-execution/order-creation-execution/ # Check the order status. print('{}: Order ref: {} / Type {} / Status {}'.format( self.data.datetime.datetime(0), order.ref, 'Buy' * order.isbuy() or 'Sell', order.getstatusname())) if (self.cross_up and self.trail_stop): self.cancel(self.trail_stop) # If it is submitted/accepted, leave the fucntion if order.status in [order.Submitted, order.Accepted]: if self.cross_up: self.cancel(self.trail_stop) print(f'{self.datas[0].datetime.datetime(0)} trying to cancel {self.trail_stop}') return
In the output log, ref: 2 is my StopTrail since we see that there is a trail amount. You can see that the bt.Order.StopTrail is dead (Alive: False), yet it is still completed? How is that possible?
2019-11-01 09:00:00: Order ref: 2 / Type Buy / Status Accepted 2019-11-01 09:00:00 trying to cancel Ref: 2 OrdType: 0 OrdType: Buy Status: 4 Status: Completed Size: 6 Price: None Price Limit: None TrailAmount: 10.97938953872858 TrailPercent: None ExecType: 5 ExecType: StopTrail CommInfo: <backtrader.comminfo.CommInfoBase object at 0x7fae48146e50> End of Session: 737363.9999999999 Info: AutoOrderedDict([('ref', '999')]) Broker: None Alive: False 2019-11-01 09:00:00: Order ref: 3 / Type Buy / Status Accepted 2019-11-01 09:00:00 trying to cancel Ref: 2 OrdType: 0 OrdType: Buy Status: 4 Status: Completed Size: 6 Price: None Price Limit: None TrailAmount: 10.97938953872858 TrailPercent: None ExecType: 5 ExecType: StopTrail CommInfo: <backtrader.comminfo.CommInfoBase object at 0x7fae48146e50> End of Session: 737363.9999999999 Info: AutoOrderedDict([('ref', '999')]) Broker: None Alive: False 2019-11-01 09:00:00: Order ref: 2 / Type Buy / Status Completed
-
RE: Bokeh Integration - Interactive Webbrowser Plotting
Hey VBS,
Awesome work with backtrader_plotting. I was wondering if there was a parameter to change the color for barup and bardown when style = 'bar'.
Also, is there a way to make a green vertical line for an executed buy and a red vertical line for an executed sell?
Thank!
-
Order.StopTrail turns positive shares into short position
Hello,
I am trying to implement a trailing stop order, and I'm using self.close with bt.Order.StopTrail. The first sell is expected, but I don't understand as to why self.close() would short the position thereafter?
if self.position.size == 0: if self.myind.ema_s[0] > self.myind.ema_l[0] and self.myind.ema_s[-1] < self.myind.ema_l[-1] and self.myind.ema_s[-2] < self.myind.ema_l[-2]: # amount to invest amount_to_invest = self.params.order_percentage * self.broker.cash self.size = math.floor(amount_to_invest/self.dataclose) # previous close less than the previous close # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy(exectype = bt.Order.Limit, price = self.dataclose[0], valid = datetime.now() + timedelta(hours = 1), size = self.size) elif self.position.size > 0: self.close(exectype=bt.Order.StopTrail, trailamount = 8)
My log is the following:
2020-08-11T02:05:30, BUY CREATE, 1586.35 2020-08-11T06:00:35, Buy Executed at 1586.35 2020-08-11, position size:5 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T13:55:13, Sell Executed at 1592.1 2020-08-11, position size:-35 2020-08-11T14:08:01, Sell Executed at 1591.6 2020-08-11, position size:-45 2020-08-11T14:08:01, Sell Executed at 1591.6 2020-08-11, position size:-45 2020-08-11T14:16:13, Sell Executed at 1590.35 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1590.35 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1590.35 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1589.75 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1589.75 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1589.75 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1589.75 2020-08-11, position size:-85 2020-08-11T14:16:13, Sell Executed at 1589.75 2020-08-11, position size:-85