Question on trailing stop orders
-
Hi,
in the example here , trail stop order is created as below
'''def next(self): if not self.position: if self.crup: o = self.buy() self.order = None print('*' * 50) elif self.order is None: if self.p.stoptype == bt.Order.StopTrailLimit: price = self.data.close[0] plimit = self.data.close[0] + self.p.limitoffset else: price = None plimit = None self.order = self.sell(exectype=self.p.stoptype, price=price, plimit=plimit, trailamount=self.p.trailamount, trailpercent=self.p.trailpercent)
'''
I have a few doubts.
-
My understanding of the code: on day 1 new buy order created and 'self.order=None'. The next day, the buy order got executed at open and 'position.size>0', then create a 'StopTrailLimit' order. On day 3, if price reached a certain level, the StopTrailLimit order got executed. What If on day 2 stop price is already reached, there is no way to stop loss because the StopTrailLimit will only be executed on the next bar after creation (which is already day 3)?? What if you want stop loss immediately take effect after position is entered on day 2 at open.
-
Suppose a StopTrailLimit is never executed and the original position has been closed. If later you want to enter into a new position, I think you have to cancel the existing StopTrailLimit order. Strangely, according to the sample code, if there is pending order (including StopTrailLimit), new buy cannot be created. StopTrailLimit does not die with the original position, but forbids creation of new position??
I tried to implement stop trail orders on my own. The strategy is long short. Can someone tell me if the implementation is correct? Thank you!
'''
def next(self): # enter into positions if self.buysell>0: self.cancel() #cancel existing stop loss orders self.buy(exectype=bt.Order.Market) #enter into new position self.stop_long = 1 #indicates a new long is just entered, need to put a stop loss sell order elif self.buysell<0: self.cancel() self.buy(exectype=bt.Order.Market) self.stop_short = 1 #create trailing stop loss orders elif self.stop_long == 1 and self.position.size>0: self.stop_long = self.sell(exectype=bt.Order.StopTrailLimit, trailpercent=self.p.trailpercent) elif self.stop_short == 1 and self.position.size<0: self.stop_short = self.buy(exectype=bt.Order.StopTrailLimit, trailpercent=self.p.trailpercent)
'''
-
-
@Yelloww said in Question on trailing stop orders:
Couple thoughts that might help or not.
My understanding of the code: on day 1 new buy order created and 'self.order=None'. The next day, the buy order got executed at open and 'position.size>0', then create a 'StopTrailLimit' order. On day 3, if price reached a certain level, the StopTrailLimit order got executed. What If on day 2 stop price is already reached, there is no way to stop loss because the StopTrailLimit will only be executed on the next bar after creation (which is already day 3)??
Correct.
What if you want stop loss immediately take effect after position is entered on day 2 at open.
If you will use
cheat-on-open
, then you will have an ability to check what is going on at day's open and issuestoptrail
order atopen
. It should be executed at the same day if condition met. Or you need to move to lower timeframe.Suppose a StopTrailLimit is never executed and the original position has been closed. If later you want to enter into a new position, I think you have to cancel the existing StopTrailLimit order.
Correct.
-
I post my own implementation of trail stop orders here. It may not be absolutely correct/optimum. Just for the reference of any one who are interested.
There are 2 rules:
- position can be both long/short
- all new long/short orders must be executed successfully.
'''
def next(self): # need to go long if self.curr_buysell[0] > 0 and self.prev_buysell <= 0 and self.position.size <= 0: if self.position.size < 0: self.close_short = self.close() # close existing positions self.close_short.addinfo(ordername="FLATSHORT") self.log('FLATSHORT CREATE, size {}'.format(self.close_short.created.size)) self.cancel(self.stop_short) self.enter_long = self.buy() self.enter_long.addinfo(ordername="LONGENTER") self.log( 'LONGENTER CREATE, close price {}, size {}'.format(self.data.close[0], self.enter_long.created.size)) self.stop_long = self.sell(exectype=self.p.stoptype, trailpercent=self.p.trailpercent) self.stop_long.addinfo(ordername="STOPLONG") # need to go short elif self.curr_buysell[0] < 0 and self.prev_buysell >= 0 and self.position.size >= 0: if self.position.size > 0: self.close_long = self.close() # close existing positions self.close_long.addinfo(ordername="FLATLONG") self.log('FLATLONG CREATE, size {}'.format(self.close_long.created.size)) self.cancel(self.stop_long) self.enter_short = self.sell() self.enter_short.addinfo(ordername="SHORTENTER") self.log( 'SHORTENTER CREATE, close price {}, size {}'.format(self.data.close[0], self.enter_short.created.size)) self.stop_short = self.buy(exectype=self.p.stoptype, trailpercent=self.p.trailpercent) self.stop_short.addinfo(ordername="STOPSHORT") self.prev_buysell = self.curr_buysell[0]
'''