Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. xisisu
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    X
    • Profile
    • Following 0
    • Followers 0
    • Topics 1
    • Posts 5
    • Best 0
    • Controversial 0
    • Groups 0

    xisisu

    @xisisu

    0
    Reputation
    329
    Profile views
    5
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    xisisu Unfollow Follow

    Latest posts made by xisisu

    • RE: Help with Simple BBand Strategy

      @Paska-Houso

      Thanks for the detailed reply!

        cerebro.broker.set_checksubmit(checksubmit=False)
      

      Fixed the problem. Thank you so much! :)

      posted in Indicators/Strategies/Analyzers
      X
      xisisu
    • RE: Help with Simple BBand Strategy

      @Paska-Houso

      Digging around, I saw there is also the option of Order.Partial, link: https://www.backtrader.com/docu/order.html

      However, seems it is not triggered automatically.

      is there a way to

      • still use the AllInSizer
      • if price gap happens, partially execute the order, and cancel the rest that cannot be filled?

      Thanks.

      posted in Indicators/Strategies/Analyzers
      X
      xisisu
    • RE: Help with Simple BBand Strategy

      Another general question:

      If we know that the AllInSizer have this price gap problem, and we cannot use it with the cheat-on-open option, what would be the correct use case for the AllInSizer?

      Thanks.

      posted in Indicators/Strategies/Analyzers
      X
      xisisu
    • RE: Help with Simple BBand Strategy

      @Paska-Houso

      Thank you so much for the detailed reply!

      I have modified my code with the cheat_on_open option, but it seems using the current open price in next_open(), not the next day open price.

      class BBand_CrossOver(bt.Strategy):
        params = (('period', 20),)
      
        def log(self, txt, dt=None):
          dt = dt or self.datas[0].datetime.date(0)
          print('{}, {}'.format(dt.isoformat(), txt))
      
        def __init__(self):
          self.dataclose = self.data0.close
          self.dataopen = self.data0.open
      
          self.bband = bt.indicators.BollingerBands(self.data0, period=self.params.period)
          self.buysig = bt.indicators.CrossOver(self.data0, self.bband.lines.bot)
          self.sellsig = bt.indicators.CrossOver(self.data0, self.bband.lines.top)
      
        def next_open(self):
          self.log('Close: %.2f, Open: %.2f' % (self.dataclose[0], self.dataopen[0]))
      
          if self.position.size:
            if self.sellsig < 0:
              self.log('SELL CREATE, size {}'.format(self.position.size))
              self.sell(size=self.position.size)
      
          elif self.buysig > 0:
            size = int(self.broker.getcash() / self.data0.open)
            self.log('BUY CREATE, cash {}, size {}, open {}, close {}'.format(self.broker.getcash(), size, self.dataopen[0], self.dataclose[0]))
            self.buy(size=size)
      
        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 enougth cash
          if order.status in [order.Completed]:
            if order.isbuy():
              self.log('BUY EXECUTED, price {}, cost {}, comm {}'.format(order.executed.price, order.executed.value,
                                                                         order.executed.comm))
            elif order.issell():
              self.log('SELL EXECUTED, price {}, cost {}, comm {}'.format(order.executed.price, order.executed.value,
                                                                          order.executed.comm))
          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 {}, NET {}'.format(trade.pnl, trade.pnlcomm))
      

      And here is the main program:

        cerebro = bt.Cerebro(cheat_on_open=True)
        data = bt.feeds.YahooFinanceData(dataname='BABA', fromdate=datetime.datetime(2016, 1, 1),
                                         todate=bt.datetime.datetime(2016, 12, 31), timeframe=bt.TimeFrame.Days,
                                         compression=1)
        cerebro.adddata(data)
        cerebro.addstrategy(BBand_CrossOver, period=20)
      
        cerebro.broker.setcash(10000.0)
        # cerebro.addsizer(bt.sizers.AllInSizer)
        # cerebro.broker.setcommission(commission=0.001)
      
        cerebro.addwriter(bt.WriterFile, csv=True, out='test.csv')
      
        print('start: {}'.format(cerebro.broker.getvalue()))
        cerebro.run(optreturn=False)
        print('finish: {}'.format(cerebro.broker.getvalue()))
        cerebro.plot()
      

      To be more specific, in the output, I have:

      2016-06-29, Close: 78.04, Open: 76.98
      2016-06-29, BUY CREATE, cash 12071.300000000001, size 156, open 76.98, close 78.04
      2016-06-29, Order Canceled/Margin/Rejected
      2016-06-30, Close: 79.53, Open: 78.31
      
      • if we use close price on 0629, size is 12071.3 / 78.04 = 154
      • if we use open price on 0629, size is 12071.3 / 76.98 = 156
      • if we use open price on 0630, size is 12071.3 / 78.31 = 154

      Seems here it is using the open price on current day, not next day.

      Any suggestions?

      posted in Indicators/Strategies/Analyzers
      X
      xisisu
    • Help with Simple BBand Strategy

      Hi,

      I am trying to work on a simple Bband strategy, where when close up cross the bband bottom line, I buy; when close down cross the bband top line, I sell.

      Here is my code:

      class BBand_CrossOver(bt.Strategy):
        params = (('period', 20),)
      
        def __init__(self):
          self.bband = bt.indicators.BollingerBands(self.data0, period=self.params.period)
          self.buysig = bt.indicators.CrossOver(self.data0, self.bband.lines.bot)
          self.sellsig = bt.indicators.CrossOver(self.data0, self.bband.lines.top)
      
        def next(self):
          if self.position.size:
            if self.sellsig < 0:
              self.sell()
      
          elif self.buysig > 0:
            self.buy()
      

      I tried symbol 'BABA' on it for 2016 data, code:

        cerebro = bt.Cerebro()
        data = bt.feeds.YahooFinanceData(dataname='BABA', fromdate=datetime.datetime(2016, 1, 1),
                                         todate=bt.datetime.datetime(2016, 12, 31), timeframe=bt.TimeFrame.Days,
                                         compression=1)
        cerebro.adddata(data)
        cerebro.addstrategy(BBand_CrossOver, period=20)
      
        cerebro.broker.setcash(10000.0)
        cerebro.addsizer(bt.sizers.AllInSizer)
      
        cerebro.addwriter(bt.WriterFile, csv=True, out='test.csv')
      
        cerebro.run(optreturn=False)
        cerebro.plot()
      

      Interestingly, it did execute some orders, but it did not trigger on all of them.
      alt text

      link: https://www.dropbox.com/s/ysrsbwzde4f00eh/BABA.png?dl=0

      You can see it triggered the buy order around Feb 5th, and Sell order around March 20th, which are expected.

      However, around June 28th, there should be a up-cross. but the buy order is not triggered.

      Is there a good way to debug this?
      Can I output the self.bband.lines and the signals in the writer as well?

      Thanks very much!

      posted in Indicators/Strategies/Analyzers
      X
      xisisu