Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    StopLoss

    General Code/Help
    2
    6
    79
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      Gerry last edited by

      Hi All,
      I am trying to code a simple trailing stop loss strategy, but I just cant seem to get the hang of it after reading most of the blog posts on the topic and the docs. Feels like a silly thing to miss but maybe somebody can help. Appreciate the assistance.
      '''
      class CustomRsi(bt.Indicator):

      lines = ('signal', 'buysig', 'sellsig', )
      
      params = (('period', 15),
      	('upperband', 80),
      	('lowerband', 33),
      	)
      
      def __init__(self):
      
      	self.lines.signal = bt.indicators.RSI_SMA(period=self.p.period)
      	self.lines.buysig = bt.ind.CrossUp(self.lines.signal, self.p.lowerband)
      	self.lines.sellsig = bt.ind.CrossDown(self.signal, self.p.upperband)
      

      class StopTrading(bt.Strategy):

      params = (
      	('lowerband', 30),
      	('upperband', 70),
      	)
      
      def print_signal(self):
      	self.log("open {:.2f}\tclose {:.2f} \thigh {:.2f} rsi {:.2f} atr {:.2f}"
      		.format(self.data.open[0],
      			self.data.close[0],
      			self.data.high[0],
      			self.rsi[0],
      			self.atr[0]
      			)
      		)
      
      def log(self, txt, dt=None):
      	dt = dt or self.datas[0].datetime.date(0)
      	print(dt.isoformat(), txt)
      
      def __init__(self):
      	self.dataclose = self.data.close
      	self.atr = bt.ind.ATR()
      	self.rsi = bt.ind.RSI_SMA(period=15)
      	self.crsi = CustomRsi() # create instance crsi
      	self.buy_signal = self.crsi.buysig # access attributes of instance created
      	self.sell_signal = self.crsi.sellsig # access attributes of instance created
      	self.order=None
      
      
      def notify_order(self, order):
      
      	if order.status in [order.Submitted, order.Accepted]:
      		return 
      
      	if order.status in [order.Completed]:
      		if order.isbuy():
      			self.log(f'Buy executed for long position {order.executed.price}')
      		elif order.issell():
      			self.log(f'Close executed for long position {order.executed.price}')
      
      	self.order = None
      
      def notify_trade(self, trade):
      	if trade.isopen:
      		return
      
      	else:
      		# Trade is closed, log profit / loss, barlen: amount of bars trade was open
      		self.log(f'Profit {trade.pnl} Trade Length: {trade.barlen}')
                                                                                                                                                                                                   
      def next(self):
      
      	self.print_signal()
      
      	if self.order:
      		return
      
      	if not self.position:
      		if self.buy_signal:
      			self.log('Going long@{:.2f}'.format(self.dataclose[0]))
      			self.order=self.buy()
      
      	elif self.position:
      		self.order=self.sell(exectype=bt.Order.StopTrail, trailamount=300)
      

      '''

      G 1 Reply Last reply Reply Quote 0
      • G
        Gerry @Gerry last edited by

        @gerry ![alt text](708f53c5-2f69-4959-bee3-d0d696c3566c-image.png image url)

        run-out 1 Reply Last reply Reply Quote 0
        • run-out
          run-out @Gerry last edited by

          @gerry Did you catch this article?

          RunBacktest.com

          G 1 Reply Last reply Reply Quote 0
          • G
            Gerry @run-out last edited by

            @run-out I have, thanks. I am getting confused between this article and these two, and how to properly use them:
            https://www.backtrader.com/blog/posts/2017-03-22-stoptrail/stoptrail/

            https://www.backtrader.com/docu/order-creation-execution/bracket/bracket/

            Is it necessary to use the stoporder in the notify class or is it actually possible to do it under the next method?

            run-out 1 Reply Last reply Reply Quote 0
            • run-out
              run-out @Gerry last edited by

              @gerry You can do it both ways. Using notify_order you are setting up the stop trail after being notified of the first order completing. If you use Bracket it does that job for you.

              RunBacktest.com

              G 1 Reply Last reply Reply Quote 0
              • G
                Gerry @run-out last edited by

                @run-out Thank you very much for the reply, appreciate the help. On the bracket order, I tried using the below code, but there seems to be an error, where am I going wrong?
                '''
                class CustomRsi(bt.Indicator):

                lines = ('signal', 'buysig', 'sellsig', )
                
                params = (('period', 15),
                	('upperband', 80),
                	('lowerband', 33),
                	)
                
                def __init__(self):
                
                	self.lines.signal = bt.indicators.RSI_SMA(period=self.p.period)
                	self.lines.buysig = bt.ind.CrossUp(self.lines.signal, self.p.lowerband)
                	self.lines.sellsig = bt.ind.CrossDown(self.signal, self.p.upperband)
                

                class StopTrading(bt.Strategy):

                params = (
                	('lowerband', 30),
                	('upperband', 70),
                	)
                
                def print_signal(self):
                	self.log("open {:.2f}\tclose {:.2f} \thigh {:.2f} rsi {:.2f} atr {:.2f}"
                		.format(self.data.open[0],
                			self.data.close[0],
                			self.data.high[0],
                			self.rsi[0],
                			self.atr[0]
                			)
                		)
                
                def log(self, txt, dt=None):
                	dt = dt or self.datas[0].datetime.date(0)
                	print(dt.isoformat(), txt)
                
                def __init__(self):
                	self.dataclose = self.data.close
                	self.atr = bt.ind.ATR()
                	self.rsi = bt.ind.RSI_SMA(period=15)
                	self.crsi = CustomRsi() # create instance crsi
                	self.buy_signal = self.crsi.buysig # access attributes of instance created
                	self.sell_signal = self.crsi.sellsig # access attributes of instance created
                	self.order=None
                
                
                def notify_order(self, order):
                
                	if order.status in [order.Submitted, order.Accepted]:
                		return 
                
                	if order.status in [order.Completed]:
                		if order.isbuy():
                			self.log(f'Buy executed for long position {order.executed.price}')
                		elif order.issell():
                			self.log(f'Close executed for long position {order.executed.price}')
                
                	self.order = None
                
                def notify_trade(self, trade):
                	if trade.isopen:
                		return
                
                	else:
                		# Trade is closed, log profit / loss, barlen: amount of bars trade was open
                		self.log(f'Profit {trade.pnl} Trade Length: {trade.barlen}')
                                                                                                                                                                                                             
                def next(self):
                
                	self.print_signal()
                
                	if self.order:
                		return
                
                	if not self.position:
                		if self.buy_signal:
                			
                			self.order=self.buy_bracket(exectype=bt.Order.StopTrail, trailamount=300)
                			self.log('Going long@{:.2f}, stoptrail {:.2f}'.format(self.dataclose[0], bt.Order.StopTrail))
                

                '''

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors