Backtrader Community

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

    HexaBraum

    @HexaBraum

    3
    Reputation
    2
    Profile views
    12
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    HexaBraum Unfollow Follow

    Best posts made by HexaBraum

    • RE: Indicator for multiple Datafeeds

      @run-out Alright I got all the problems fixed for now. Thank you very much for your help and the fast answers.

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out I fixed it by also adding the buy and sell statements into the for loop in next. However the buys and sells still don´t get displayed in the plot and it doesn´t seem to buy and sell everytime the price is above/under the top/bot-band. So my main problem right now is the plot missing the buys and sells.
      Thats my current code:

      import backtrader as bt
      import backtrader.feeds as btfeed
      import datetime
      
      
      # from datetime import datetime
      
      class dataFeed(btfeed.GenericCSVData):
          params = (
              ('dtformat', '%Y-%m-%d %H:%M:%S'),
              ('datetime', 0),
              ('open', 1),
              ('high', 2),
              ('low', 3),
              ('close', 4),
              ('volume', 5),
              ('openinterest', -1)
          )
      
      
      class firstStrategy(bt.Strategy):
          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):
      
              # self.dataclose = self.datas[0].close
      
              self.bb_inds = dict()
              for d in self.datas:
                  bb = bt.ind.BollingerBands(d, period=21, devfactor=2.0,
                                             movav=bt.ind.MovAv.Simple)
                  self.bb_inds[d] = dict()
                  self.bb_inds[d]["bb_top"] = bb.top
                  self.bb_inds[d]["bb_bot"] = bb.bot
      
      
          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, %.2f' % order.executed.price)
                  elif order.issell():
                      self.log('SELL EXECUTED, %.2f' % order.executed.price)
      
                  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 next(self):
              for d in self.datas:
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  # Simply log the closing price of the series from the reference
                 # self.log('Close, %.2f' % d.close[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:
                  if d.close[0] < self.bb_inds[d]["bb_bot"][0]:
      
                      # current close less than previous close
      
                      # if self.dataclose[-1] < self.dataclose[-2]:
                      # previous close less than the previous close
      
                      # BUY, BUY, BUY!!! (with default parameters)
                      self.log('BUY CREATE, %.2f' % d.close[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      #self.order = self.buy()
                      self.buy(data=d)
      
                  # Already in the market ... we might sell
                  if d.close[0] > self.bb_inds[d]["bb_top"][0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % d.close[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      #self.order = self.sell()
                      self.sell(data=d)
      
      
      if __name__ == '__main__':
          # Create a cerebro entity
          cerebro = bt.Cerebro()
          startcash = 10000
      
          # Add a strategy
          cerebro.addstrategy(firstStrategy)
      #    cerebro.addindicator(BollingerBands)
      
          datalist = [("AM.ATVI.csv"), ("AM.MO.csv"), ("AM.GM.csv"), ("AM.CL.csv")]
      
          for i in range(len(datalist)):
              data = dataFeed(dataname=datalist[i], timeframe=bt.TimeFrame.Minutes, compression=1)
              cerebro.adddata(data, name=datalist[i])
      
          # Set our desired cash start
          cerebro.broker.setcash(startcash)
      
          # Set the commission
          # cerebro.broker.setcommission(commission=0.0005)
      
          # Add a sizer
          # cerebro.addsizer(bt.sizers.PercentSizer, percents=50)
      
          cerebro.run()
          # Print out the starting conditions
          print('Starting Portfolio Value: %.2f' % startcash)
      
          # Get final portfolio Value
          portvalue = cerebro.broker.getvalue()
          pnl = portvalue - startcash
      
          # Print out the final result
          print('Final Portfolio Value: ${}'.format(portvalue))
          print('P/L: ${}'.format(pnl))
          cerebro.plot()
      

      My plot:
      Plot.PNG

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out Thank you very much, that helps a lot. Now there is still the problem that the buy and sell signals dont really work. It seems like the order is created for stock1 but executed for stock2. When I use your code from above with my CSV Datafiles and i dont log the closing price but only the orders this is my output:

      2021-02-18, BUY CREATE, 43.76
      2021-02-18, BUY EXECUTED, 101.03
      Starting Portfolio Value: 10000.00
      Final Portfolio Value: $10001.244999999999
      P/L: $1.2449999999989814

      Furthermore the buys and sells dont get displayed in the plot. Unfortunately I can´t find the mistake/s.

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum

    Latest posts made by HexaBraum

    • RE: Bollinger Band Strategy does not work properly

      Fixed it.

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out Alright I got all the problems fixed for now. Thank you very much for your help and the fast answers.

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • Bollinger Band Strategy does not work properly

      Even though the buy and sell signals get triggered it seems like the orders get executed delayed or whatever. Here is my code for init and next:

          def __init__(self):
      
              # self.dataclose = self.datas[0].close
      
              self.bb_inds = dict()
              for d in self.datas:
                  bb = bt.ind.BollingerBands(d, period=21, devfactor=2.0,
                                             movav=bt.ind.MovAv.Simple)
                  self.bb_inds[d] = dict()
                  self.bb_inds[d]["bb_top"] = bb.top
                  self.bb_inds[d]["bb_bot"] = bb.bot
      
      
          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, %.2f' % order.executed.price)
                  elif order.issell():
                      self.log('SELL EXECUTED, %.2f' % order.executed.price)
      
                  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 next(self):
              for d in self.datas:
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  # Simply log the closing price of the series from the reference
                 # self.log('Close, %.2f' % d.close[0])
      
              # Check if we are in the market
              #if not self.position:
                  if d.close[0] < self.bb_inds[d]["bb_bot"][0]:
      
                      # BUY, BUY, BUY!!! (with default parameters)
                      self.log('BUY CREATE, %.2f' % d.close[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      #self.order = self.buy()
                      self.buy(data=d, size=1, price=d.close[0])
      
                  # Already in the market ... we might sell
                  if d.close[0] > self.bb_inds[d]["bb_top"][0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % d.close[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      #self.order = self.sell()
                      self.sell(data=d, size=1, price=d.close[0])
      

      The plot:
      Plot.PNG

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out I fixed it by also adding the buy and sell statements into the for loop in next. However the buys and sells still don´t get displayed in the plot and it doesn´t seem to buy and sell everytime the price is above/under the top/bot-band. So my main problem right now is the plot missing the buys and sells.
      Thats my current code:

      import backtrader as bt
      import backtrader.feeds as btfeed
      import datetime
      
      
      # from datetime import datetime
      
      class dataFeed(btfeed.GenericCSVData):
          params = (
              ('dtformat', '%Y-%m-%d %H:%M:%S'),
              ('datetime', 0),
              ('open', 1),
              ('high', 2),
              ('low', 3),
              ('close', 4),
              ('volume', 5),
              ('openinterest', -1)
          )
      
      
      class firstStrategy(bt.Strategy):
          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):
      
              # self.dataclose = self.datas[0].close
      
              self.bb_inds = dict()
              for d in self.datas:
                  bb = bt.ind.BollingerBands(d, period=21, devfactor=2.0,
                                             movav=bt.ind.MovAv.Simple)
                  self.bb_inds[d] = dict()
                  self.bb_inds[d]["bb_top"] = bb.top
                  self.bb_inds[d]["bb_bot"] = bb.bot
      
      
          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, %.2f' % order.executed.price)
                  elif order.issell():
                      self.log('SELL EXECUTED, %.2f' % order.executed.price)
      
                  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 next(self):
              for d in self.datas:
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  # Simply log the closing price of the series from the reference
                 # self.log('Close, %.2f' % d.close[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:
                  if d.close[0] < self.bb_inds[d]["bb_bot"][0]:
      
                      # current close less than previous close
      
                      # if self.dataclose[-1] < self.dataclose[-2]:
                      # previous close less than the previous close
      
                      # BUY, BUY, BUY!!! (with default parameters)
                      self.log('BUY CREATE, %.2f' % d.close[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      #self.order = self.buy()
                      self.buy(data=d)
      
                  # Already in the market ... we might sell
                  if d.close[0] > self.bb_inds[d]["bb_top"][0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % d.close[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      #self.order = self.sell()
                      self.sell(data=d)
      
      
      if __name__ == '__main__':
          # Create a cerebro entity
          cerebro = bt.Cerebro()
          startcash = 10000
      
          # Add a strategy
          cerebro.addstrategy(firstStrategy)
      #    cerebro.addindicator(BollingerBands)
      
          datalist = [("AM.ATVI.csv"), ("AM.MO.csv"), ("AM.GM.csv"), ("AM.CL.csv")]
      
          for i in range(len(datalist)):
              data = dataFeed(dataname=datalist[i], timeframe=bt.TimeFrame.Minutes, compression=1)
              cerebro.adddata(data, name=datalist[i])
      
          # Set our desired cash start
          cerebro.broker.setcash(startcash)
      
          # Set the commission
          # cerebro.broker.setcommission(commission=0.0005)
      
          # Add a sizer
          # cerebro.addsizer(bt.sizers.PercentSizer, percents=50)
      
          cerebro.run()
          # Print out the starting conditions
          print('Starting Portfolio Value: %.2f' % startcash)
      
          # Get final portfolio Value
          portvalue = cerebro.broker.getvalue()
          pnl = portvalue - startcash
      
          # Print out the final result
          print('Final Portfolio Value: ${}'.format(portvalue))
          print('P/L: ${}'.format(pnl))
          cerebro.plot()
      

      My plot:
      Plot.PNG

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @hexabraum I just tested it with more than 2 Stocks and it seems like only the very first stock in the ticker list gets bought or sold even though the order was created for another stock.

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out Thank you very much, that helps a lot. Now there is still the problem that the buy and sell signals dont really work. It seems like the order is created for stock1 but executed for stock2. When I use your code from above with my CSV Datafiles and i dont log the closing price but only the orders this is my output:

      2021-02-18, BUY CREATE, 43.76
      2021-02-18, BUY EXECUTED, 101.03
      Starting Portfolio Value: 10000.00
      Final Portfolio Value: $10001.244999999999
      P/L: $1.2449999999989814

      Furthermore the buys and sells dont get displayed in the plot. Unfortunately I can´t find the mistake/s.

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out Thanks but that doesn´t really help me. My problem is that the Bollinger Bands only work for my first data feed and also only get plotted for my first datafeed. Therefore the other securities are not in consideration to be bought or sold. Plot.PNG

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Indicator for multiple Datafeeds

      @run-out 4 securities equal one backtest, however each datafeed gets a technical analysis and therefore buy or sell signals for this exact security. I want the backtrader to backtest my strategy on multiple datafeeds. I hope that i got the point :D

      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • Indicator for multiple Datafeeds

      The Bollinger Bands work for the first Data File, so it´s the only one where Orders are created.
      Additionally the buys and sells dont get displayed, Where is the mistake?
      Thanks for your help :)

      import backtrader as bt
      import backtrader.feeds as btfeed
      from datetime import datetime
      
      class dataFeed(btfeed.GenericCSVData):
          params = (
              ('dtformat', '%Y-%m-%d %H:%M:%S'),
              ('datetime', 0),
              ('open', 1),
              ('high', 2),
              ('low', 3),
              ('close', 4),
              ('volume', 5),
              ('openinterest', -1)
          )
      
      class BollingerBands(bt.Indicator):
          lines = ('topband', 'botband')
          params = (('period', 21), ('devfactor', 2.0), ('movav', bt.ind.MovAv.Simple),)
      
          plotinfo = dict(subplot=False)
      
          def _plotlabel(self):
              plabels = [self.p.period, self.p.devfactor]
              plabels += [self.p.movav] * self.p.notdefault('movav')
              return plabels
      
          def __init__(self):
              bb = bt.ind.BollingerBands(
                  period=self.p.period, devfactor=self.p.devfactor, movav=self.p.movav)
      
      class firstStrategy(bt.Strategy):
          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):
              self.dataclose = self.datas[0].close
              bb = bt.ind.BollingerBands(
                  period=21, devfactor=2.0, movav=bt.ind.MovAv.Simple)
              self.lines.topband = bb.top
              self.lines.botband = bb.bot
      
      
          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, %.2f' % order.executed.price)
                  elif order.issell():
                      self.log('SELL EXECUTED, %.2f' % order.executed.price)
      
                  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 next(self):
              for d in self.datas:
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  # Simply log the closing price of the series from the reference
                  self.log('Close, %.2f' % d.close[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:
                  if self.dataclose[0] < self.lines.botband[0]:
                      # current close less than previous close
      
                      # if self.dataclose[-1] < self.dataclose[-2]:
                      # previous close less than the previous close
      
                      # BUY, BUY, BUY!!! (with 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()
      
                  # Already in the market ... we might sell
                  if self.dataclose[0] > self.lines.topband[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()
          startcash = 10000
      
          # Add a strategy
          cerebro.addstrategy(firstStrategy)
          cerebro.addindicator(BollingerBands)
      
          datalist = [("AM.ATVI.csv"), ("AM.MO.csv"), ("AM.GM.csv"), ("AM.CL.csv")]
          """  , ("AM.FDX.csv"), ("AM.NAKD.csv"), ("AM.NVDA.csv"), ("AM.OCGN.csv"), ("AM.ON.csv")
              , ("AM.PDD.csv"), ("AM.PLUG.csv"), ("AM.QCOM.csv"), ("AM.MDLZ.csv"), ("AM.ADP.csv")
              , ("AM.C.csv"), ("AM.AZN.csv"), ("AM.PEP.csv"), ("AM.ORCL.csv"), ("AM.QTT.csv")
              , ("AM.RUN.csv"), ("AM.SABR.csv"), ("AM.SNDL.csv"), ("AM.TSLA.csv"), ("AM.UAL.csv")
              , ("AM.UXIN.csv"), ("AM.WEN.csv"), ("AM.WFC.csv"), ("AM.YY.csv"), ("AM.ZNGA.csv")
              , ("AM.MSFT.csv"), ("AM.AAPL.csv"), ("AM.FB.csv"), ("AM.BABA.csv"), ("AM.TSM.csv")
              , ("AM.V.csv"), ("AM.JPM.csv"), ("AM.JNJ.csv")
              , ("AM.PG.csv"), ("AM.BAC.csv"), ("AM.INTC.csv"), ("AM.VZ.csv"), ("AM.NKE.csv")
              , ("AM.XOM.csv"), ("AM.KO.csv"), ("AM.T.csv"), ("AM.PFE.csv")
              , ("AM.MRK.csv"), ("AM.MS.csv"), ("AM.AAL.csv"), ("AM.GT.csv"), ("AM.UBER.csv")
              , ("AM.AMD.csv"), ("AM.PDD.csv"), ("AM.CVX.csv")]"""
      #the files are located in my python project
          for i in range(len(datalist)):
              data = dataFeed(dataname=datalist[i], timeframe=bt.TimeFrame.Minutes, compression=60)
              cerebro.adddata(data, name=datalist[i])
      
          # Set our desired cash start
          cerebro.broker.setcash(startcash)
      
          # Set the commission
          #cerebro.broker.setcommission(commission=0.0005)
      
          # Add a sizer
          #cerebro.addsizer(bt.sizers.PercentSizer, percents=50)
      
          cerebro.run()
          # Print out the starting conditions
          print('Starting Portfolio Value: %.2f' % startcash)
      
          # Get final portfolio Value
          portvalue = cerebro.broker.getvalue()
          pnl = portvalue - startcash
      
          # Print out the final result
          print('Final Portfolio Value: ${}'.format(portvalue))
          print('P/L: ${}'.format(pnl))
          cerebro.plot()
      
      posted in Indicators/Strategies/Analyzers
      H
      HexaBraum
    • RE: Adding Multiple CSV data feeds

      @hexabraum i fixed it by deleting the for loop in the log function.

      posted in General Code/Help
      H
      HexaBraum