Navigation

    Backtrader Community

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

    tmi

    @tmi

    1
    Reputation
    157
    Profile views
    2
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    tmi Unfollow Follow

    Best posts made by tmi

    • RE: Extending Datafeeds GenericCSV Attribute Error

      @michael172 Hi there, I'm having the same issue that you did: the error message "module 'backtrader.feeds' has no attribute 'symbolroll'" (symbolroll being my own creation). So I think my data feeder isn't being accepted. Could you perhaps share your code or portion of your code that you changed to solve the issue? Many thanks!

      @Osofuego Could you share what changes to Michael's code would have fixed this issue? Many thanks again!

      posted in Indicators/Strategies/Analyzers
      T
      tmi

    Latest posts made by tmi

    • Error: When strings show up where they aren't wanted...

      Hi, thanks in advance for anyone's assistance here. I'm trying to backtest using my own data stored in a local CSV file. It's a relatively straightforward project (it's a riff on the Quickstart guide model). but I have hit a wall that has left me spinning my wheels for too long. (There doesn't appear to be a current thread that addresses this specific error message...). My CSV has 6 columns of data: one datetime time series, and 5 custom indicators (no OHLC data). When I upload my data with the custom parameters adjusted for my custom data and I run it, I get a "TypeError: must be real number, not str" stemming from an issue "self.array[self.idx + ago] = value" stemming from line 222 in the linebuffer.py. I'm pretty sure my data is uploading correctly (printing the head shows everything is normal) but clearly I'm producing strings where I need to have only int. Can someone please advise if they know where this newbie got trapped? Many thanks!
      Relevant code:

      
      lines = (
              'Date',
              'Abra1',
              'Abra2',
              'Abra3',
              'Abra4',
              'Abra5',
      )
      
      params = (
      
              ('dtformat', '%m/%d/%Y'),
      
              ('Date', 0),
              ('time', -1),
              ('open', -1),
              ('high', -1),
              ('low', -1),
              ('close', -1),
              ('volume', -1),
              ('openinterest', -1),
              ('Abra1', 1),
              ('Abra2', 2),
              ('Abra3', 3),
              ('Abra4', 4),
              ('Abra5', 5),
      )
      
      datafields = btfeeds.PandasData.datafields + (['Date', 'Abra1', 'Abra2', 'Abra3', "Abra4", "Abra5"])
      
      mydict = dict(lines=tuple(lines), params=params, datafields=bt.feeds.PandasData.datafields + list(lines),)
      
      PandasDataAbra = type('PandasDataAbra', (btfeeds.PandasData,), mydict)
      
      dataframe = pd.read_csv("C:/Users/user/PycharmProjects/sampledata.csv",
                                  skiprows=0,
                                  header=0,
                                  parse_dates=True,
                                  )
      
          data = PandasDataAbra(dataname=dataframe)
      

      Error:

      File "C:\Users\user\PycharmProjects\venv\lib\site-packages\backtrader\linebuffer.py", line 222, in __setitem__
          self.array[self.idx + ago] = value
      TypeError: must be real number, not str
      

      Head (to check out underlying data):

       Date   Abra1   Abra2   Abra3   Abra4  Abra5
      0  3/26/2007  1.2628  1.3365  16.632  18.135  0.845
      1  3/27/2007  2.4871  0.1935  16.776  18.265  0.875
      2  3/28/2007 -1.3629 -0.4005  17.268  18.577  0.450
      3  3/29/2007 -2.8490 -0.1530  17.376  18.577  0.140
      4  3/30/2007 -0.8008 -0.3105  17.400  18.603  0.415
      

      All code:

      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 pandas as pd
      import backtrader as bt
      import pandas as pd
      import backtrader.feeds as btfeeds
      from backtrader.feeds import GenericCSVData
      from backtrader.feeds import PandasData
      from backtrader import Cerebro
      from backtrader import feed
      
      
      lines = (
              'Date',
              'Abra1',
              'Abra2',
              'Abra3',
              'Abra4',
              'Abra5',
      )
      
      params = (
      
              ('dtformat', '%m/%d/%Y'),
      
              ('Date', 0),
              ('time', -1),
              ('open', -1),
              ('high', -1),
              ('low', -1),
              ('close', -1),
              ('volume', -1),
              ('openinterest', -1),
              ('Abra1', 1),
              ('Abra2', 2),
              ('Abra3', 3),
              ('Abra4', 4),
              ('Abra5', 5),
      )
      
      datafields = btfeeds.PandasData.datafields + (['Date', 'Abra1', 'Abra2', 'Abra3', "Abra4", "Abra5"])
      
      mydict = dict(lines=tuple(lines), params=params, datafields=bt.feeds.PandasData.datafields + list(lines),)
      
      PandasDataAbra = type('PandasDataAbra', (btfeeds.PandasData,), mydict)
      
      class TestStrategy(bt.Strategy):
      
          def log(self, txt, dt=None):
              ''' Logging function for 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.dataAbra4 = self.datas[0].Abra4
      
              # To keep track of pending orders and buy price/commission
              self.order = None
              self.buyprice = None
              self.buycomm = None
      
          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.Abra4[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.Abra4[0] > self.Abra2[0] and self.Abra4[0] > 0:
      
                          # BUY, BUY, BUY!!! (with default parameters)
                          self.log('BUY CREATE, %.2f' % self.Abra4[0])
      
                          # Keep track of the created order to avoid a 2nd order
                          self.order = self.buy()
              else:
      
                  # Already in the market ... we might sell
                  if self.Abra4[0] < self.Abra2[0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % self.F4[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.sell()
      
      if __name__ == '__main__':
          cerebro: Cerebro = bt.Cerebro()
      
          cerebro.addstrategy(TestStrategy)
      
          dataframe = pd.read_csv("C:/Users/user/PycharmProjects/sampledata.csv",
                                  skiprows=0,
                                  header=0,
                                  parse_dates=True,
                                  )
      
          data = PandasDataAbra(dataname=dataframe)
      
          cerebro.adddata(data)
      
          cerebro.broker.setcash(100000.0)
      
          cerebro.addsizer(bt.sizers.FixedSize, stake=10)
      
          cerebro.broker.setcommission(commission=0.001)
      
          print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
          print(dataframe.head())
          cerebro.run()
      
          print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          # cerebro.plot()
      
      posted in General Code/Help
      T
      tmi
    • RE: Extending Datafeeds GenericCSV Attribute Error

      @michael172 Hi there, I'm having the same issue that you did: the error message "module 'backtrader.feeds' has no attribute 'symbolroll'" (symbolroll being my own creation). So I think my data feeder isn't being accepted. Could you perhaps share your code or portion of your code that you changed to solve the issue? Many thanks!

      @Osofuego Could you share what changes to Michael's code would have fixed this issue? Many thanks again!

      posted in Indicators/Strategies/Analyzers
      T
      tmi