Backtrader Community

    • 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/

    Wrong selling notifications

    General Code/Help
    1
    2
    92
    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.
    • Y
      Youssef 0 last edited by

      Hi,
      I am new to all of python, backtrader and trading in general, I am trying to understand what my strategy does.

      What I am trying to do is the following :
      The basic strategy is a crossover strategy between two exponential moving averages.
      When the crossover indicator is greater than 0 I create a target buy order with a size of 2%. At the same time, I create a stop loss order at a certain trigger price.
      when the crossover indicator is smaller than 0, I close my position.

      I also defined a notification function to understand what my strategy does, here is my code :

      import backtrader as bt
      import backtrader.indicators as btind
      from indicators.sdvRatio import sdvRatio 
      import backtrader as bt
      import datetime
      
      class barycentreStrat(bt.Strategy): 
          # Strategy parameters
          params = (
          ('pfast',5),
          ('pslow',10),
          ('devfactor',2),
          ('bolPeriod',21),
          ('rsiPeriod',21),
          ('rsiU',70),
          ('rsiL',30),
          ('pme1',12),
          ('pme2',26),
          ('psignal',9),
          ('percents',0.02),
          ('trail',False))
      
      
      
          def __init__(self):
              # variable definitions
              self.dataclose = self.datas[0].close
              self.datahigh = self.datas[0].high
              self.datalow = self.datas[0].low
              self.datavolume=self.datas[0].volume
              # Order variable will contain ongoing order details/status
              self.order = None
              self.buy_ord=None
              self.sell_ord=None
              self.cl_ord=None
      
      
              
              # Instantiate moving averages and crossover indicator
              self.slow_ema=btind.ExponentialMovingAverage(self.datas[0],period=self.params.pslow,plot=True)
              self.fast_ema=btind.ExponentialMovingAverage(self.datas[0],period=self.params.pfast,plot=True)
              self.SFCrossover=btind.CrossOver(self.fast_ema,self.slow_ema,plot=True)#slow fast crossover
      
          def log(self, txt, dt=None):
              dt = dt or self.datas[0].datetime.date(0)
              print(f'{dt.isoformat()} {txt}') 
      
          def orderLog(self,order,date):
              print('-'*32,' NOTIFY ORDER ','-'*32)
              print('{} '.format(order.info['name']))
              print('{}, Ref: {},Size: {}, Price: {}'.format(
                                                          date,
                                                          order.ref,
                                                          order.size,
                                                          'NA' if not order.price else round(order.price,5)
                                                          ))
      
          def next(self):
              if self.order:
                  return
              # crossover signals using fast and slow EMAs 
              if not self.position: 
                  # We are not in the market, look for a signal to OPEN trades
                  if self.SFCrossover > 0: 
                      # Keep track of the created order to avoid a 2nd order
                      self.buy_ord = self.order_target_percent(target=self.p.percents)    
                      self.buy_ord.addinfo(name="Long entry")                
              else:
                  # We are already in the market, look for a signal to CLOSE trades
                  if self.SFCrossover < 0:
                      self.cl_ord = self.close()      
                      self.cl_ord.addinfo(name="Closing position")                
      
          def notify_order(self, order):
              date = self.data.datetime.date()
              long_stop=self.dataclose[0]-1
              # Check if an order has been completed
              if order.status in [order.Completed]:#
                  if order.isbuy():
                      self.orderLog(order,date)
                      self.log(order.Status[order.status])
                      if not self.p.trail:
                          self.sl_ord = self.close(exectype=bt.Order.Stop, price=long_stop)
                          self.sl_ord.addinfo(name='Long Stop Loss')
                          self.orderLog(self.sl_ord,date)
                          self.log(order.Status[order.status])
                          self.log('direct.print')
      
      
                  elif order.issell():
                      self.orderLog(order,date)
                      self.log(order.Status[order.status])
                      self.log('sell.print')
      
      
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
      
      
      
      dateOne="1 Jan, 2017"
      dateTwo="1 Jun, 2021"
      symbol="BNBUSDT"
      interval="1d"
      
      
      
      
      
      cerebro = bt.Cerebro(stdstats=True)
      data = bt.feeds.GenericCSVData(
          dataname='data\crypto\BNBUSDT1d1 Jan, 20171 Jun, 2021',
          fromdate=datetime.datetime(2018, 1, 30),
          todate=datetime.datetime(2018, 4, 28),
          nullvalue=0.0,
          dtformat=('%Y-%m-%d %H:%M:%S'),
          datetime=0,
          open=1,
          high=2,
          low=3,
          close=4,
          volume=5,
          openinterest=-1
      
      )
      
      cerebro.adddata(data)
      
      #Add strategy to Cerebro
      cerebro.addstrategy(barycentreStrat)  
      
      
      if __name__ == '__main__':
          start_portfolio_value = cerebro.broker.getvalue()
          cerebro.run()
          end_portfolio_value = cerebro.broker.getvalue()
          pnl = end_portfolio_value - start_portfolio_value
          print(f'Starting Portfolio Value: {start_portfolio_value:2f}')
          print(f'Final Portfolio Value: {end_portfolio_value:2f}')
          print(f'PnL: {pnl:.2f}')
          cerebro.plot()
      
      
      
      
      
      exit()
      

      the result :

      
      
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long entry 
      2018-02-15, Ref: 1,Size: 19, Price: 10.4096
      2018-02-15 Completed
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long Stop Loss
      2018-02-15, Ref: 2,Size: -19, Price: 9.8661
      2018-02-15 Completed
      2018-02-15 direct.print
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long Stop Loss
      2018-02-20, Ref: 2,Size: -19, Price: 9.8661
      2018-02-20 Completed
      2018-02-20 sell.print
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long entry 
      2018-02-28, Ref: 3,Size: 18, Price: 10.56
      2018-02-28 Completed
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long Stop Loss
      2018-02-28, Ref: 4,Size: -18, Price: 9.4536
      2018-02-28 Completed
      2018-02-28 direct.print
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long Stop Loss
      2018-03-06, Ref: 4,Size: -18, Price: 9.4536
      2018-03-06 Completed
      2018-03-06 sell.print
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long entry
      2018-03-21, Ref: 5,Size: 21, Price: 9.1618
      2018-03-21 Completed
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long Stop Loss
      2018-03-21, Ref: 6,Size: -21, Price: 8.9777
      2018-03-21 Completed
      2018-03-21 direct.print
      --------------------------------  NOTIFY ORDER  --------------------------------
      Closing position
      2018-04-18, Ref: 7,Size: -21, Price: NA
      2018-04-18 Completed
      2018-04-18 sell.print
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long entry
      2018-04-22, Ref: 8,Size: 15, Price: 13.3302
      2018-04-22 Completed
      --------------------------------  NOTIFY ORDER  --------------------------------
      Long Stop Loss
      2018-04-22, Ref: 9,Size: -15, Price: 11.8888
      2018-04-22 Completed
      2018-04-22 direct.print
      Starting Portfolio Value: 10000.000000
      Final Portfolio Value: 10037.282000
      PnL: 37.28
      

      I understand the first and second messages : the crossover happens and I create a buy order and a stop loss, but what is this third message ? it should be a "closing position" (I want it to be)message, much like the second to last message !
      I do not understand it especially since it seems that the selling does happen according to the picture :
      capture.PNG

      My code is a patchwork of lots of different codes I found on the web so it is not good looking, but I hope it's understandable.

      I do not know how to include the data , sorry !

      I know this is a newbie question as I do not yet fully understand the order mecanism. Why does this happen ?
      also am I doing what I want to do ?
      Thank you for your help.

      1 Reply Last reply Reply Quote 0
      • Y
        Youssef 0 last edited by

        Thank you everyone for reading, I understood the problem but don't know how to delete the topic, the notifications are actually good, my stop loss was just triggered without me realizing it because I did not use the candlestick style.

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