Orders not executed after a certain time period
-
I'm not sure what the bug is but when I change the length of the data being backtested, the orders stop being executed after a while. Here's what I mean:
2012 - 2020:
2019 - 2020:
I don't get why the orders clump up like that for the 2012 - 2020 backtest and don't have any many orders for 2019 (when there are when we limit the backtest period to 2019).
Code as follows:
Strategy:
class RSIStrat(bt.Strategy): def __init__(self): self.dataclose= self.datas[0].close # Keep a reference to the "close" line in the data[0] dataseries self.rsi= bt.indicators.RelativeStrengthIndex() self.stoch = bt.indicators.Stochastic() self.ATR= bt.indicators.AverageTrueRange(period=7) self.MAC = bt.indicators.MACDHisto() self.order = None # Property to keep track of pending orders. There are no orders when the strategy is initialized. self.buyprice = None self.buycomm = None def log(self, txt, dt=None): # Logging function for the strategy. 'txt' is the statement and 'dt' can be used to specify a specific datetime dt = dt or self.datas[0].datetime.date(0) print('{0},{1}'.format(dt.isoformat(),txt)) def notify_order(self, order): # 1. If order is submitted/accepted, do nothing if order.status in [order.Submitted, order.Accepted]: return # 2. If order is buy/sell executed, report price executed if order.status in [order.Completed]: if order.isbuy(): self.log('BUY EXECUTED, Price: {0:8.2f}, Cost: {1:8.2f}, Comm: {2:8.2f}'.format( order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: self.log('SELL EXECUTED, {0:8.2f}, Cost: {1:8.2f}, Comm{2:8.2f}'.format( order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) #when was trade executed # 3. If order is canceled/margin/rejected, report order canceled elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self,trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS {0:8.2f}, NET {1:8.2f}'.format( trade.pnl, trade.pnlcomm)) def next(self): # Log the closing prices of the series from the reference # self.log('Close, {0:8.2f}'.format(self.dataclose[0])) if self.order: # check if order is pending, if so, then break out return # since there is no order pending, are we in the market? if not self.position: # not in the market if (self.rsi < 50) and (self.MAC < 0) and (self.stoch < 50): price = self.dataclose[0] price_limit = price - (2.8*self.ATR) price_stop = price + (1.2*self.ATR) atr_price = self.ATR[0] self.order = self.sell_bracket( size=100, price=price, stopprice=price_stop, limitprice=price_limit, ) self.log('SHORT AT: {:8.2f}, Limit: {:8.2f}, Stop: {:8.2f}, ATR: {}'.format(price,price_limit,price_stop,atr_price)) elif (self.rsi > 50) and (self.stoch.k > 50) and (self.MAC > 0): price = self.dataclose[0] price_limit = price + (2.8*self.ATR) price_stop = price - (1.2*self.ATR) atr_price = self.ATR[0] self.order = self.buy_bracket( size=100, price=price, stopprice=price_stop, limitprice=price_limit, ) self.log('BUY AT: {:8.2f}, Limit: {:8.2f}, Stop: {:8.2f}, ATR: {}'.format(price,price_limit,price_stop,atr_price))
Cerebro:
if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(RSIStrat) cerebro.broker.setcash(100000.0) cerebro.broker.setcommission(commission=0.001) data = bt.feeds.YahooFinanceData(dataname='AMD', fromdate=datetime(2012, 1, 1), todate=datetime(2020, 1, 1)) cerebro.adddata(data) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Ending Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.plot()
Would appreciate any help. Thanks!
-
@zachlim98
Hi,can you post a log?
-
Are your buy and sell brackets reversed?
-
@run-out Hi! Thanks for your reply. I've tried both ways though, putting the buy bracket first and then the sell bracket and results are unfortunately still the same. It's so strange because it clearly works on shorter backtest periods.
-
@Jonny8 Hi! Thanks for your reply. Sure, will post one later but it's basically what you see in the plot. Just two clusters of orders around those periods for the 2012 - 2020 backtest period
-
@Jonny8 Hey there! I have the log and I think I see the problem. It appears that there is a long gap (between 2012 and 2016) where my order is ordered but not executed
2012-05-29,OPERATION PROFIT, GROSS -26.82, NET -28.07 2012-05-29,SHORT AT: 6.46, Limit: 5.74, Stop: 6.77 2016-07-25,SELL EXECUTED, 6.46, Cost: -646.00, Comm 0.65 2016-07-26,BUY EXECUTED, Price: 6.77, Cost: -646.00, Comm: 0.68
Why do you think that could be the case?
-
@zachlim98 said in Orders not executed after a certain time period:
price = self.dataclose[0]
You could be setting an order for the price and the price moves away from it, never filling. You should use
valid
to cancel the order if it is not filled within n bars. -
@run-out Ah I see! Thanks so much for your help. Yes, I changed it to a marker order instead of a limit order and it ran well.