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/

    Problem with bt.sizers.FixedSize, when stake is an integar larger than 3

    General Code/Help
    1
    2
    29
    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.
    • weibudda
      weibudda last edited by

      When I try the order-history.py in the samples distributed with the source code, a problem occurs.

      The code is as follows:

      import backtrader as bt
      
      ORDER_HISTORY = (
          ('2005-02-01', 1, 2984.63),
          ('2005-03-04', -1, 3079.93),
          ('2005-03-08', 1, 3113.82),
          ('2005-03-22', -1, 3040.55),
      )
      
      
      class St(bt.Strategy):
          params = dict(
          )
      
          def notify_order(self, order):
              if not order.alive():
                  print(','.join(str(x) for x in
                                 (self.data.num2date(order.executed.dt).date(),
                                  order.executed.size * 1 if order.isbuy() else -1,
                                  order.executed.price)))
      
          def notify_trade(self, trade):
              if trade.isclosed:
                  print('profit {}'.format(trade.pnlcomm))
      
          def __init__(self):
              print('Creating Empty Strategy')
              pass
      
          def next(self):
              pass
      
      
      def runstrat():
          cerebro = bt.Cerebro()
          data0 = bt.feeds.BacktraderCSVData(dataname='../../datas/2005-2006-day-001.txt')
          cerebro.adddata(data0)
          cerebro.broker.setcash(5000000000.0)
          # Broker
          cerebro.broker = bt.brokers.BackBroker()
          # Sizer
          cerebro.addsizer(bt.sizers.FixedSize)
          # Strategy
          cerebro.addstrategy(St)
          cerebro.add_order_history(ORDER_HISTORY, notify=True)
      
          cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Months)
          cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Years)
          cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)
      
          # Execute
          cerebro.run()
          # cerebro.plot()
      
      
      if __name__ == '__main__':
          runstrat()
      

      the corresponding outputs:

      Creating Empty Strategy
      2005-02-01,1,2984.63
      2005-03-04,-1,3079.93
      profit 95.29999999999973
      2005-03-08,1,3113.82
      2005-03-22,-1,3040.55
      profit -73.26999999999998
      

      Everything are OK now. But when I change the ORDER_HISTORY, problems occurs:

      ORDER_HISTORY = (
          ('2005-02-01', 2, 2984.63),
          ('2005-03-04', -2, 3079.93),
          ('2005-03-08', 1, 3113.82),
          ('2005-03-22', -1, 3040.55),
      )
      
      'The profit of each trade is right, but the size of the close(sell) order is WRONG!'
      'The output:'
      
      Creating Empty Strategy
      2005-02-01,2,2984.63
      2005-03-04,-1,3079.93
      profit 190.59999999999945
      2005-03-08,1,3113.82
      2005-03-22,-1,3040.55
      profit -73.26999999999998
      

      When stake is larger than 3, things will be even worse:

      ORDER_HISTORY = (
          ('2005-02-01', 4, 2984.63),
          ('2005-03-04', -4, 3079.93),
          ('2005-03-08', 1, 3113.82),
          ('2005-03-22', -1, 3040.55),
      )
      
      'The size of the buy will always be 0, and that of the close(sell) orders will always be -1!'
      'Profit of each trade is missing!'
      'The output:'
      
      Creating Empty Strategy
      2005-02-01,0,0.0
      2005-03-04,-1,3079.93
      2005-03-08,1,3113.82
      2005-03-22,-1,3040.55
      

      What's the Problem?

      Additionally, to check if the problem relates to the cerebro.add_order_history(ORDER_HISTORY, notify=True) function, the samples with a normal SmaCross strategy is also tested. The results show that, when using the function cerebro.addsizer(bt.sizers.FixedSize, stake=3), when stake is an integar larger than 3, similar problem also occurs.

      The code:

      import backtrader as bt
      
      
      class SmaCross(bt.SignalStrategy):
          params = dict(sma1=10, sma2=20)
      
          def notify_order(self, order):
              if not order.alive():
                  print(','.join(str(x) for x in
                                 (self.data.num2date(order.executed.dt).date(),
                                  order.executed.size * 1 if order.isbuy() else -1,
                                  order.executed.price)))
      
          def notify_trade(self, trade):
              if trade.isclosed:
                  print('profit {}'.format(trade.pnlcomm))
      
          def __init__(self):
              print('Creating Signal Strategy')
              sma1 = bt.ind.SMA(period=self.params.sma1)
              sma2 = bt.ind.SMA(period=self.params.sma2)
              crossover = bt.ind.CrossOver(sma1, sma2)
              self.signal_add(bt.SIGNAL_LONG, crossover)
      
      def runstrat():
          cerebro = bt.Cerebro()
          data0 = bt.feeds.BacktraderCSVData(dataname='../../datas/2005-2006-day-001.txt')
          cerebro.adddata(data0)
          cerebro.broker.setcash(5000000000.0)
          # Broker
          cerebro.broker = bt.brokers.BackBroker()
          # Sizer
          cerebro.addsizer(bt.sizers.FixedSize, stake=3)
          # Strategy
          cerebro.addstrategy(SmaCross)
          cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Months)
          cerebro.addanalyzer(bt.analyzers.TimeReturn, timeframe=bt.TimeFrame.Years)
          cerebro.addanalyzer(bt.analyzers.TradeAnalyzer)
          # Execute
          cerebro.run()
          # cerebro.plot()
      
      
      if __name__ == '__main__':
          runstrat()
      

      The output:

      Creating Signal Strategy
      2005-02-01,3,2984.6299999999997
      2005-03-04,-1,3079.93
      profit 285.90000000000055
      2005-03-08,3,3113.82
      2005-03-22,-1,3040.5500000000006
      profit -219.80999999999995
      ...
      

      The profit of each trade is right, but the size of the close(sell) order is WRONG!

      when stake=4, the output:

      Creating Signal Strategy
      2005-02-01,0,0.0
      2005-03-08,0,0.0
      2005-04-08,0,0.0
      2005-05-13,0,0.0
      

      Since using bt.SIGNAL_LONG, the size of the buy will always be 0, no close(sell) orders
      when using the bt.SIGNAL_LONGSHORT signal, similar results occurs as the order_history

      Creating Signal Strategy
      2005-02-01,0,0.0
      2005-03-04,-1,3079.93
      2005-03-08,0,0.0
      2005-03-08,4,3113.82
      profit -135.5600000000013
      2005-03-22,-1,3040.55
      2005-04-08,0,0.0
      2005-04-08,4,3092.07
      

      The strange thing occurs, no trade is closed, but the profit reports!

      1 Reply Last reply Reply Quote 0
      • weibudda
        weibudda last edited by

        Problem has been solved!

        in the above code, the cash in the broker has been set before the broker has been declared. So, in the newly defined broker, the cash is limited. When stake is large, the order will be rejected due to not enougth cash.

            cerebro.broker = bt.brokers.BackBroker()
            cerebro.broker.setcash(50000000.0)
        
        1 Reply Last reply Reply Quote 0
        • 1 / 1
        • First post
          Last post
        Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
        $(document).ready(function () { app.coldLoad(); }); }