Buy/Sell Markers
-
I noticed that the when using multiple data feeds, the buy and sell markers can appear on different dates even though
notify_order()
reports them both being filled on the same date.Not sure if this is a misunderstanding on my part or not....
Anyway, I created an example script to reproduce the phenomenon. The script will attempt to use
order_target_percent()
at fixed dates. As such, I would expect them to be filled on the same date (which they appear to be!)import backtrader as bt from datetime import datetime class TestStrategy(bt.Strategy): def __init__(self): pass def next(self): for i, d in enumerate(self.datas): dt = d.datetime.datetime().date() dn = d._name pos = self.getposition(d).size #print(dt,type(dt)) if dt == datetime(2017,6,1).date(): print('{} Sending Order: {} | Current Pos: {}'.format(dt,dn,pos)) if dn == 'AAPL': self.order_target_percent(d, target=0.3) else: self.order_target_percent(d, target=0.7) if dt == datetime(2017,9,1).date(): print('{} Sending Order: {} | Current Pos: {}'.format(dt,dn,pos)) if dn == 'AAPL': self.order_target_percent(d, target=0.1) else: self.order_target_percent(d, target=0.1) def notify_order(self, order): date = self.data.datetime.datetime().date() if order.status == order.Completed: print('{} >> Order Completed >> Stock: {}, Ref: {}, Size: {}, Price: {}'.format( date, order.data._name, order.ref, order.size, 'NA' if not order.price else round(order.price,5) )) def notify_trade(self, trade): date = self.data.datetime.datetime().date() if trade.isclosed: print('{} >> Notify Trade >> Stock: {}, Close Price: {}, Profit, Gross {}, Net {}'.format( date, trade.data._name, trade.price, round(trade.pnl,2), round(trade.pnlcomm,2))) startcash = 10000 #Create an instance of cerebro cerebro = bt.Cerebro() # data lists data = bt.feeds.Quandl( dataname='AAPL', fromdate = datetime(2017,1,1), todate = datetime(2018,1,1), buffered= True ) data2 = bt.feeds.Quandl( dataname='F', fromdate = datetime(2017,1,1), todate = datetime(2018,1,1), buffered= True ) data_list = [(data, 'AAPL'), (data2, 'F')] #Add our strategy cerebro.addstrategy(TestStrategy) # Create a Data Feed for asset in data_list: # Add the data cerebro.adddata( asset[0], name=asset[1]) # Set our desired cash start cerebro.broker.setcash(startcash) cerebro.broker.set_checksubmit(False) # Run over everything cerebro.run() cerebro.plot(style='candlestick')
This will then result in an output and chart that looks like this:
Am I being a dumbo and missing something obvious?
-
I don't think so. The data feeds don't probably fully align, but there is only a master temporal axis which is tied to the strategy which is the one used by the observers. The wrongly displaced marker cannot have happened where displayed, because the price from the order execution is not reached (it is reached in the previous bar, which matches the log)