Orders created but never completed
-
Hi,
I'm new to backtrader and I'm attempting to customize the sample strategy from the quickstart. I have a problem that my orders are being created, however, they are not being executed. If I put a debugger on the notify_order, it's only called twice. one for submitted and for accepted. Nothing else. Can you please assist. I'm working with 1m kline data.
Here's a sample of my data
Date,Open,High,Low,Close,Volume,Adjusted 2018-02-28 12:23:59.999,210.26,210.37,210.25,210.26,28.25449,210.26 2018-02-28 12:24:59.999,210.26,210.41,210.22,210.25,39.63167,210.25 2018-02-28 12:25:59.999,210.25,210.51,210.2,210.44,128.18018,210.44 2018-02-28 12:26:59.999,210.59,210.89,210.27,210.89,41.63106,210.89 2018-02-28 12:27:59.999,210.89,210.89,210.21,210.55,99.96582,210.55 2018-02-28 12:28:59.999,210.49,210.99,210.4,210.46,54.72677,210.46 2018-02-28 12:29:59.999,210.51,210.51,210.4,210.47,8.85311,210.47 2018-02-28 12:30:59.999,210.47,210.47,210.4,210.4,36.46703,210.4 2018-02-28 12:31:59.999,210.41,211.0,210.4,210.95,156.99139,210.95 2018-02-28 12:32:59.999,210.94,211.3,210.79,210.8,70.39553,210.8 2018-02-28 12:33:59.999,210.81,210.9,210.81,210.85,21.47947,210.85 2018-02-28 12:34:59.999,210.85,210.9,210.7,210.71,154.64939,210.71 2018-02-28 12:35:59.999,210.88,211.0,210.71,211.0,81.00914,211.0 2018-02-28 12:36:59.999,211.02,211.25,210.57,210.57,158.20673,210.57 2018-02-28 12:37:59.999,210.57,211.09,210.28,210.53,223.22261,210.53
This is the sample code.
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import os.path # To manage paths import sys # To find out the script name (in argv[0]) # Import the backtrader platform import backtrader as bt # Create a Stratey class TestStrategy(bt.Strategy): params = ( ('maperiod', 15), ) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.time() print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None sma = bt.indicators.SMA(self.data, period=self.params.maperiod) self.crossover = bt.indicators.CrossOver(self.data, sma) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do return print(order.status) # Check if an order has been completed # Attention: broker could reject order if not enough cash if order.status in [order.Complete]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Cancelled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') # Write down: no pending order self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) # Not yet ... we MIGHT BUY if ... if self.crossover > 0: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.buy() elif self.crossover < 0: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.sell() if __name__ == '__main__': # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.optstrategy(TestStrategy) # Datas are in a subfolder of the samples. Need to find where the script is # because it could have been called from anywhere modpath = os.path.dirname(os.path.abspath(sys.argv[0])) datapath = os.path.abspath('/home/ubuntu/git/bt/data/sample_data.txt') # Create a Data Feed data = bt.feeds.BacktraderCSVData( dataname=datapath, # Do not pass values before this date sessionstart=datetime.datetime(2018, 2, 27, 12, 23, 59), # Do not pass values before this date sessionend=datetime.datetime(2018, 2, 28, 16, 35, 59), # Do not pass values after this date timeframe=bt.TimeFrame.Minutes, compression=1, reverse=False ) # Add the Data Feed to Cerebro cerebro.adddata(data) # Set our desired cash start cerebro.broker.setcash(100000.0) cerebro.broker.set_checksubmit(False) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run(optreturn=False) # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Plot the result cerebro.plot()
This is what my output looks like.
16:35:59, Close, 208.53 16:35:59, Close, 208.55 16:35:59, Close, 208.72 16:35:59, Close, 208.12 16:35:59, Close, 207.69 16:35:59, SELL CREATE, 207.69 16:35:59, Close, 208.10 16:35:59, Close, 208.20 16:35:59, BUY CREATE, 208.20 16:35:59, Close, 207.96 16:35:59, SELL CREATE, 207.96 16:35:59, Close, 207.55 16:35:59, Close, 207.77 16:35:59, Close, 208.13 16:35:59, Close, 208.60 16:35:59, BUY CREATE, 208.60 16:35:59, Close, 208.50 16:35:59, Close, 208.58 16:35:59, Close, 208.53 16:35:59, Close, 208.53 16:35:59, Close, 208.54
-
The log shows that the time is not moving forward ... in your timeframe (
Minutes
,1
). It would be inconceivable for orders to be executed.@greenkode said in Orders created but never completed:
sessionstart=datetime.datetime(2018, 2, 27, 12, 23, 59), # Do not pass values before this date sessionend=datetime.datetime(2018, 2, 28, 16, 35, 59),
Probably because you are confusing
fromdate
andtodate
withsessionstart
andsessionend
-
@backtrader said in Orders created but never completed:
The log shows that the time is not moving forward ... in your timeframe (
Minutes
,1
). It would be inconceivable for orders to be executed.@greenkode said in Orders created but never completed:
sessionstart=datetime.datetime(2018, 2, 27, 12, 23, 59), # Do not pass values before this date sessionend=datetime.datetime(2018, 2, 28, 16, 35, 59),
Probably because you are confusing
fromdate
andtodate
withsessionstart
andsessionend
But it's only a very long shot.
-
Thanks,
I modified it to use a generic csv reader
# Create a Data Feed data = bt.feeds.GenericCSVData( dataname=datapath, # Do not pass values before this date fromdate=datetime.datetime(2018, 2, 28, 12, 23, 59), # Do not pass values after this date todate=datetime.datetime(2018, 2, 28, 16, 35, 59), datetime=0, open=1, high=2, low=3, close=4, timeframe=bt.TimeFrame.Minutes, compression=1, reverse=False )
And it works now.