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

trailing stoploss



  • I read the page on trailing stoplosses here https://www.backtrader.com/docu/order-creation-execution/trail/stoptrail/

    I don't really understand what is going on. In the code below, I'm using the percentage stoploss at 2%. I would like to be able to see how the stoplosses change using the log but I'm not sure how to refer to it.
    From the log it doesn't seem that no trades are getting stopped out, however the equity at the end does slightly change. even if I would use an extremely small percentage stoploss, I would expect that most trades would get stopped out right away, I don't see a change in the log in the days where the trades are being bought or sold.

    Ideally I would also use an ATR stoploss but that I don't see how to implement it.

    class Strategy(bt.Strategy):
        
        lines = ('SlowEMA', 'FastEMA',)
        
        def log(self, txt, dt=None):
            ''' Logging function for this strategy'''
            dt = dt or self.datas[0].datetime.datetime(0)
            print('%s, %s' % (dt.strftime("%Y-%m-%d %H:%M"), txt))    
        
        def __init__(self):
            
            self.FastEMA = bt.indicators.ExponentialMovingAverage(self.datas[0], period=50)
            self.SlowEMA = bt.indicators.ExponentialMovingAverage(self.datas[0], period=200)
            self.crup = bt.ind.CrossUp(self.FastEMA, self.SlowEMA)
            self.crdown = bt.ind.CrossUp(self.SlowEMA,self.FastEMA)
            self.RSI = bt.indicators.RSI(self.datas[0])
            
            # To keep track of pending orders and buy price/commission
            self.order = None
            self.buyprice = None
            self.buycomm = None
            
        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
    
            # Check if an order has been completed
            # Attention: broker could reject order if not enough cash
            if order.status in [order.Completed]:
                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.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 %.2f, NET %.2f' %
                     (trade.pnl, trade.pnlcomm))
            
        def next(self):
            
            
            # Check if an order is pending ... if yes, we cannot send a 2nd one
            if self.order:
                return
            
            # Check if we are in the market
            if not self.position:
            
            # Not yet ... we MIGHT BUY if ...
                if self.crup[0] == 1:
                        self.log('BUY CREATE, %.2f' % self.data.close[0])
                        self.order = self.buy(price=self.data.close[0], exectype=bt.Order.StopTrail, trailpercent=0.002)
                        
                elif self.crdown[0] == 1:
                        self.log('SHORT CREATE, %.2f' % self.data.close[0])
                        self.order = self.sell(price=self.data.close[0], exectype=bt.Order.StopTrail, trailpercent=0.002)              
                          
            else:
    
                # Already in the market ... we might sell
                if self.crdown[0] ==1:
                    self.log('SELL CREATE, %.2f' % self.data.close[0])
                    self.order = self.sell()
                    
                elif self.crup[0] ==1:
                    self.log('SHORT COVER CREATE, %.2f' % self.data.close[0])
                    self.order = self.buy()
                    
      
    if __name__ == '__main__':
    
        cerebro = bt.Cerebro()
    
        # Add a strategy
        cerebro.addstrategy(Strategy)
        
        # Create a Data Feed
        data = bt.feeds.PandasData(dataname=df)
        
        # Add the Data Feed to Cerebro
        cerebro.adddata(data)
        
        # Add a FixedSize sizer according to the stake
        cerebro.addsizer(bt.sizers.PercentSizer, percents=10)
        
        # Set the commission for 0.1%
        cerebro.broker.setcommission(commission=0.001)
        
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        SR = cerebro.run()
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
        
        # Plot the result
        cerebro.plot()
    


  • Have a look at my post here.


Log in to reply
 

});