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/

    Need help to add a simple stop loss

    General Code/Help
    1
    1
    35
    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.
    • Jeffreylabranche
      Jeffreylabranche last edited by

      Hi,

      I'm just starting to learn Python and Backtrader. Any idea how I can add a stop loss to this strategy? I want to replace the actual exit which is based on the moving average by a 2% stop loss. Unfortunately was not able to do it based on Backtrader documentation.

      Thank you in advance!

      code_text
      

      from future import (absolute_import, division, print_function,
      unicode_literals)

      import datetime # For datetime objects
      import os.path # To manage paths
      import sys # To find out the script name (in argv[0])
      import backtrader.feeds as btfeeds
      #from backtrader_plotting import Bokeh

      from matplotlib.dates import (HOURS_PER_DAY, MIN_PER_HOUR, SEC_PER_MIN,
      MONTHS_PER_YEAR, DAYS_PER_WEEK,
      SEC_PER_HOUR, SEC_PER_DAY,
      num2date, rrulewrapper, YearLocator,
      MicrosecondLocator)

      #import matplotlib
      #import matplotlib.pyplot as plt
      #import backtrader.plot

      #matplotlib.use('Qt5Agg')
      #plt.switch_backend('Qt5Agg')

      Import the backtrader platform

      import backtrader as bt

      Create a Stratey

      class TestStrategy(bt.Strategy):
      params = (
      ('maperiod', 10),
      )

      def log(self, txt, dt=None):
          ''' Logging function fot this strategy'''
          dt = dt or self.datas[0].datetime.date(0)
          print('%s, %s' % (dt.isoformat(), txt))
      
      def __init__(self):
          # Keep a reference to the "close" line in the data[0] dataseries
          self.dataclose = self.datas[0].close
      
          # To keep track of pending orders and buy price/commission
          self.order = None
          self.buyprice = None
          self.buycomm = None
      
          # Add a MovingAverageSimple indicator
          self.sma = bt.indicators.SimpleMovingAverage(
              self.datas[0], period=self.params.maperiod)
      
          # Indicators for the plotting show
          bt.indicators.ExponentialMovingAverage(self.datas[0], period=25)
          bt.indicators.WeightedMovingAverage(self.datas[0], period=25,
                                              subplot=True)
          bt.indicators.StochasticSlow(self.datas[0])
          bt.indicators.MACDHisto(self.datas[0])
          rsi = bt.indicators.RSI(self.datas[0])
          bt.indicators.SmoothedMovingAverage(rsi, period=10)
          bt.indicators.ATR(self.datas[0], plot=False)
      
      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')
      
          # Write down: no pending order
          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):
          # Simply log the closing price of the series from the reference
          self.log('Close, %.2f' % self.dataclose[0])
      
          # 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.dataclose[0] > self.sma[0]:
      
                  # BUY, BUY, BUY!!! (with all possible default parameters)
                  self.log('BUY CREATE, %.2f' % self.dataclose[0])
      
                  # Keep track of the created order to avoid a 2nd order
                  self.order = self.buy()
      
          else:
      
              if self.dataclose[0] < self.sma[0]:
                  # SELL, SELL, SELL!!! (with all possible default parameters)
                  self.log('SELL CREATE, %.2f' % self.dataclose[0])
      
                  # Keep track of the created order to avoid a 2nd order
                  self.order = self.sell()
      

      if name == 'main':
      # Create a cerebro entity
      cerebro = bt.Cerebro()

      cerebro.addstrategy(TestStrategy)
      
      
      # Create a Data Feed
      data = btfeeds.GenericCSVData(dataname='/Users/jeffrey/Documents/Python_projects/spy_data_1min.csv',
      fromdate=datetime.datetime(2022, 3, 30),
      todate=datetime.datetime(2022, 4, 18),
      nullvalue=0.0,
      datetime=0,
      #timeframe=bt.TimeFrame.Minutes,
      dtformat=('%Y-%m-%d %H:%M'),
      open=1,
      high=2,
      low=3,
      close=4,
      volume=5,
      openinterest=-1
      )    
      
      # Add the Data Feed to Cerebro
      cerebro.adddata(data)
      
      # Set our desired cash start
      cerebro.broker.setcash(100000.0)
      
      # Add a FixedSize sizer according to the stake
      cerebro.addsizer(bt.sizers.FixedSize, stake=10)
      
      # Set the commission - 0.1% ... divide by 100 to remove the %
      cerebro.broker.setcommission(commission=0.001)
      
      # Print out the starting conditions
      print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
      # Run over everything
      cerebro.run()
      
      # Print out the final result
      print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
       # Plot the result
      #b = Bokeh(style='bar', plot_mode='single')
      cerebro.plot()
      #cerebro.plot(height= 30, iplot= False)
      
      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors