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.