For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Updating Stop Loss based on current profit



  • Hi,

    I am currently issuing a bracket order as follows:

    self.buy_bracket(exectype=bt.Order.Market,
                                     size=qty,
                                     limitprice=cash*3*self.p.risk / qty + self.data.close[0],
                                     stopprice=stop_price,
                                     )
    

    I wish to update the stop order issue based on the profit of the current trade. There is only one trade open at any given moment. I tried to use the trail order and trailpercent method but it doesn't seem to work.

    In general, here's what I would like the system to do:

    if profit > 20, stop loss should be at break-even
    if profit > 40, stop loss should be at 20
    ... and so on.

    Any clever ideas on how to implement it?



  • If you really want action like in that last paragraph, than each next() you cancel existing stop order, calculate profit and new stop price, and issue new stop order. No bracket orders required.

    But it seems that it is not that easy.



  • Cool, thanks!



  • You can manage the stoplimit prices by resetting the price in the stop order. Set the initial stop order manually after the buy, then reset the stop price as price climbs. This has the advantage of not creating and cancelling stop orders over and over.

    I'm not 100% sure this is acceptable to change the price of the outstanding stop order this way, but it's working on my machine.

    You can set the price manually any way you wish.

    I borrowed this code from here.

    class BaseStrategy(bt.Strategy):
        params = dict(fast_ma=10, slow_ma=20,)
    
        def __init__(self):
            self.reset_price = 0
            self.so = []
    
            # omitting a data implies self.datas[0] (aka self.data and self.data0)
            fast_ma = bt.ind.EMA(period=self.p.fast_ma)
            slow_ma = bt.ind.EMA(period=self.p.slow_ma)
            # our entry point
            self.crossup = bt.ind.CrossUp(fast_ma, slow_ma)
    
    
    class ManualStopOrStopTrail(BaseStrategy):
        params = dict(
            stop_loss=0.15,  # price is .15 below the purchase price at intervals.
        )
    
        def notify_order(self, order):
            if not order.status == order.Completed:
                return  # discard any other notification
    
            if order.status == order.Canceled:
                return
    
            if not self.position:  # we left the market
                print("SELL@price: {} {:.2f}".format(self.date, order.executed.price))
                self.so = []
                return
    
            # We have entered the market
            print("BUY @price: {} {:.2f}".format(self.date, order.executed.price))
    
            stop_price = order.executed.price - self.p.stop_loss
            self.so = [self.sell(exectype=bt.Order.Stop, price=stop_price)]
            self.reset_price = order.executed.price + self.p.stop_loss
    
        def next(self):
            self.date = self.data.datetime.date()
            print("{} {:.2f}".format(self.date, self.data[0]))
    
            if len(self.so) > 0 and self.datas[0].close[0] > self.reset_price:
                new_stop_price = self.reset_price - self.p.stop_loss
                print("{} Stop price changed to: {:.2f}".format(self.date, new_stop_price))
                # Change the price in the order in the self.so list.
                self.so[0].created.price = new_stop_price
                # Reset the next price limit
                self.reset_price = self.reset_price + self.p.stop_loss
            else:
                pass
    
            if not self.position and self.crossup > 0:
                # not in the market and signal triggered
                self.buy()
    
    

    Here's an output using .15 cent intervals.

    2004-03-23 22.04
    2004-03-24 22.25
    2004-03-25 23.47
    BUY @price: 2004-03-25 23.38
    2004-03-26 23.57
    2004-03-26 Stop price changed to: 23.38
    2004-03-29 23.84
    2004-03-29 Stop price changed to: 23.52
    2004-03-30 24.39
    2004-03-30 Stop price changed to: 23.67
    2004-03-31 24.24
    2004-03-31 Stop price changed to: 23.82
    2004-04-01 24.73
    2004-04-01 Stop price changed to: 23.97
    2004-04-02 25.08
    2004-04-02 Stop price changed to: 24.12
    2004-04-05 25.00
    2004-04-05 Stop price changed to: 24.27
    SELL@price: 2004-04-05 24.27
    2004-04-06 24.39
    2004-04-07 24.17
    2004-04-08 28.11
    2004-04-12 27.57
    
    


  • It will most probably not work in real live trading. For this to work updating the 'order.created.price' should generate some sort of notification to the broker , and I think there is no such functionality.


Log in to reply
 

});