Multiple trades Long/Short Support?
-
Hey everyone
Newly enlisted backtrader here, I have been looking at youtube tutorials and the documentation. A lot of the examples cover 1 position at a time such as SMA crossover.
However I am trying to have multiple buy orders using 1R/R of my portfolio for each trade, regardless of whether I am in a trade or not I want each one to be individually dealt with. The logic for entering long trades is working, however I am using a buy bracket since I need a log to see if the order is executed and if it has been executed, to set a close long either at target or stop price.
If anyone can help guide me, would be extremely grateful as to how I should formulate the logic in Python?
class TestStrategy(bt.Strategy):
def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.order = None self.dataclose = self.datas[0].close self.dataopen = self.datas[0].open self.zone = self.datas[0].close - self.datas[0].open def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) self.log('Open, %.2f' % self.dataopen[0]) self.log('Zone, %.2f' % self.zone[0]) self.log('shift, %.2f' % self.zone[-1]) print(len(self)) print(self.order) print(self.position) # """Enters Long position if below conditions are met""" if self.zone[0] < 0: print("Bar is red") # current close less than previous close if self.zone[1] > 0: print("Next candle is green") # Next close less than the previous close if 1.5*abs(self.zone[0]) < abs(self.zone[1]): print("Buy Zone found") # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # self.buy() self.order = self.buy_bracket(limitprice=self.dataopen[0], price=self.dataopen[0], stopprice=self.dataclose[0]) # print(self.order) print(type(self.order.ref))
-
I would suggest you replace you
self.order
parameter with a dictionary perhaps. ALSO, you can add a paramtertradeid
in thebuy_bracket
method.Consider, for example:
def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.order = {} self.id = 0 self.dataclose = self.datas[0].close self.dataopen = self.datas[0].open self.zone = self.datas[0].close - self.datas[0].open def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) self.log('Open, %.2f' % self.dataopen[0]) self.log('Zone, %.2f' % self.zone[0]) self.log('shift, %.2f' % self.zone[-1]) print(len(self)) print(self.order) print(self.position) # """Enters Long position if below conditions are met""" if self.zone[0] < 0: print("Bar is red") # current close less than previous close if self.zone[1] > 0: print("Next candle is green") # Next close less than the previous close if 1.5*abs(self.zone[0]) < abs(self.zone[1]): print("Buy Zone found") # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # self.buy() self.order[self.id] = self.buy_bracket(tradeid = self.id, limitprice=self.dataopen[0], price=self.dataopen[0], stopprice=self.dataclose[0]) # print(self.order) print(type(self.order.ref)) self.id += 1 # this is a simple way, but you can therefore have an id to identify each individual trade
This specific method might not solve your question as you might loose track of what
self.id
fits with which order. I do feel, however, that this is a starting point for you to have a dictionary of all your submitted order.POSSIBLE SOLUTION: I have quite a different way to do it (might get a bit lost now, but putting it here for incase it helps).
I have a custom order tracking dictionary from which I track all my OPEN ORDERS (orders (buylimits, selllimits, etc.) and trades (long, short, etc.)). At times, my strategy has up to 14 trades open and this works 100%.
This is a snippet of myself.open_orders
tracking when making a BUY trade (opening a long position). My strategy logic, therefore ALWAYS looks at what trades are currently open, what orders are pending, and makes logical decisions on that# backtrader built-in action self.buy_bracket(tradeid = self.id, exectype = bt.Order.Market, price = close, size = 0.1, limitprice = self.tp, stopprice = self.sl) # self custom order tracking self.open_orders[self.id] = {'symbol' : 'EURUSD', 'lots' : 0.1, 'type' : 'buy', 'open_price' : close, 'open_time' : self.datetime.time(ago=0).isoformat(), 'SL' : self.sl, 'TP' : self.tp, 'pnl' : 0.0, 'commission' : 0.01 'swap' : 0.0, 'comment' : ''}
Note, as I can always view
self.open_orders
, I know exactly which trade I can identify when I need to make any action on it. For example, if I need to close the trade, I can sayself.close(tradeid=self.id)
and it will close the position and calculate my PnL.