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/

    Price: nan with custom data feed

    General Code/Help
    datafeed json positions price
    1
    1
    430
    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.
    • Eycke Langhans
      Eycke Langhans last edited by

      Hello community! I’m quite new to backtrader and struggeling since two days with the following problem:

      I have a simple RSI strategy (originally from https://backtest-rookies.com/) which works fine with data from bt.feeds.YahooFinanceCSVData. In my custom data feed I can see all OHLCV values, but after a buy or sell the Price attribute in self.position is always nan:

      2015-02-10 23:00:00, buy, 16.81
      --- Position Begin
      - Size: 1
      - Price: nan
      - Price orig: 0.0
      - Closed: 0
      - Opened: 1
      - Adjbase: 16.85
      --- Position End
      

      Custom data feed class (DataFeeds/MyJSONFeed.py):

      from backtrader.feed import DataBase
      from backtrader import date2num, TimeFrame
      
      
      class MyJSONFeed(DataBase):
          params = (('dataname', None),
                    ('fromdate', datetime.datetime.min),
                    ('todate', datetime.datetime.max),
                    ('symbol', None),
                    ('name', ''),
                    ('compression', 1),
                    ('timeframe', TimeFrame.Days),
                    ('sessionend', None))
      
          def __init__(self, *args, **kwargs):
              super(DataBase).__init__()
              self.server = "http://urlToAPI.json"
              self.timeframe = 'D'
              self.granularity = self.timeframe
              if self.p.timeframe == TimeFrame.Minutes:
                  self.timeframe = 'M'
                  self.granularity = self.timeframe + str(self.p.compression)
      
              postParameter = {
                  'data[instrument]': self.p.symbol,
                  'data[granularity]': self.granularity,
                  'data[from]': str(self.p.fromdate),
                  'data[to]': str(self.p.todate),
              }
              self.payload = urllib.parse.urlencode(postParameter)
              self.headers = {
                  'Content-Type': 'application/x-www-form-urlencoded'
              }
      
              self.index = 0
              self.result = None
      
          def start(self):
              response = requests.request("POST", self.server, headers=self.headers, data=self.payload)
              self.result = json.loads(response.text.encode('utf8'))
              print(self.result)
              self.index = 0
      
          def _load(self):
              if self.index >= len(self.result):
                  return False
              one_row = self.result[self.index]
              self.lines.datetime[0] = date2num(datetime.datetime.strptime(one_row["time"], '%Y-%m-%d %H:%M:%S.%f'))
              self.lines.high[0] = float(one_row["high"])
              self.lines.low[0] = float(one_row["low"])
              self.lines.close[0] = float(one_row["close"])
              self.lines.volume[0] = int(float(one_row["volume"]))
              self.lines.openinterest[0] = -1
              self.index += 1
              return True
      
      

      The JSON looks like

      [
          {
              "time": "2015-01-01 23:00:00.000000",
              "open": 15.74,
              "high": 16.07,
              "low": 15.54,
              "close": 15.76,
              "volume": 9606
          },
          {
              "time": "2015-01-04 23:00:00.000000",
              "open": 15.8,
              "high": 16.27,
              "low": 15.65,
              "close": 16.19,
              "volume": 21820
          },
          {
              "time": "2015-01-05 23:00:00.000000",
              "open": 16.2,
              "high": 16.73,
              "low": 16.12,
              "close": 16.54,
              "volume": 24917
          },
          {
              "time": "2015-01-06 23:00:00.000000",
              "open": 16.53,
              "high": 16.66,
              "low": 16.3,
              "close": 16.53,
              "volume": 22613
          },
          {
              "time": "2015-01-07 23:00:00.000000",
              "open": 16.55,
              "high": 16.66,
              "low": 16.31,
              "close": 16.36,
              "volume": 15618
          },
          {
              "time": "2015-01-08 23:00:00.000000",
              "open": 16.38,
              "high": 16.63,
              "low": 16.2,
              "close": 16.5,
              "volume": 25345
          },
          {
              "time": "2015-01-11 23:00:00.000000",
              "open": 16.49,
              "high": 16.68,
              "low": 16.43,
              "close": 16.58,
              "volume": 14853
          },
          {
              "time": "2015-01-12 23:00:00.000000",
              "open": 16.57,
              "high": 17.2,
              "low": 16.57,
              "close": 17.06,
              "volume": 25565
          },
          {
              "time": "2015-01-13 23:00:00.000000",
              "open": 17.04,
              "high": 17.09,
              "low": 16.55,
              "close": 16.85,
              "volume": 36333
          },
          {
              "time": "2015-01-14 23:00:00.000000",
              "open": 16.86,
              "high": 17.23,
              "low": 16.7,
              "close": 16.96,
              "volume": 53752
          },
          {
              "time": "2015-01-15 23:00:00.000000",
              "open": 16.94,
              "high": 17.84,
              "low": 16.89,
              "close": 17.8,
              "volume": 56762
          },
          {
              "time": "2015-01-18 23:00:00.000000",
              "open": 17.81,
              "high": 18.01,
              "low": 17.61,
              "close": 17.7,
              "volume": 21925
          },
          {
              "time": "2015-01-19 23:00:00.000000",
              "open": 17.7,
              "high": 18.03,
              "low": 17.63,
              "close": 18,
              "volume": 23881
          },
          {
              "time": "2015-01-20 23:00:00.000000",
              "open": 17.99,
              "high": 18.49,
              "low": 17.9,
              "close": 18.13,
              "volume": 48124
          },
          {
              "time": "2015-01-21 23:00:00.000000",
              "open": 18.12,
              "high": 18.48,
              "low": 17.9,
              "close": 18.33,
              "volume": 48511
          },
          {
              "time": "2015-01-22 23:00:00.000000",
              "open": 18.34,
              "high": 18.4,
              "low": 18.11,
              "close": 18.29,
              "volume": 30369
          },
          {
              "time": "2015-01-25 23:00:00.000000",
              "open": 18.31,
              "high": 18.48,
              "low": 17.86,
              "close": 17.92,
              "volume": 26849
          },
          {
              "time": "2015-01-26 23:00:00.000000",
              "open": 17.94,
              "high": 18.21,
              "low": 17.49,
              "close": 18.07,
              "volume": 23625
          },
          {
              "time": "2015-01-27 23:00:00.000000",
              "open": 18.06,
              "high": 18.16,
              "low": 17.93,
              "close": 18,
              "volume": 20791
          },
          {
              "time": "2015-01-28 23:00:00.000000",
              "open": 17.98,
              "high": 18.04,
              "low": 16.74,
              "close": 16.95,
              "volume": 44092
          },
          {
              "time": "2015-01-29 23:00:00.000000",
              "open": 16.97,
              "high": 17.32,
              "low": 16.82,
              "close": 17.24,
              "volume": 28803
          },
          {
              "time": "2015-02-01 23:00:00.000000",
              "open": 17.25,
              "high": 17.34,
              "low": 17,
              "close": 17.21,
              "volume": 21213
          },
          {
              "time": "2015-02-02 23:00:00.000000",
              "open": 17.21,
              "high": 17.75,
              "low": 17.08,
              "close": 17.29,
              "volume": 28780
          },
          {
              "time": "2015-02-03 23:00:00.000000",
              "open": 17.32,
              "high": 17.67,
              "low": 17.17,
              "close": 17.38,
              "volume": 28170
          },
          {
              "time": "2015-02-04 23:00:00.000000",
              "open": 17.39,
              "high": 17.5,
              "low": 16.93,
              "close": 17.27,
              "volume": 20148
          },
          {
              "time": "2015-02-05 23:00:00.000000",
              "open": 17.25,
              "high": 17.38,
              "low": 16.56,
              "close": 16.73,
              "volume": 33005
          },
          {
              "time": "2015-02-08 23:00:00.000000",
              "open": 16.8,
              "high": 17.17,
              "low": 16.7,
              "close": 17,
              "volume": 13733
          },
          {
              "time": "2015-02-09 23:00:00.000000",
              "open": 17.02,
              "high": 17.11,
              "low": 16.74,
              "close": 16.93,
              "volume": 13049
          },
          {
              "time": "2015-02-10 23:00:00.000000",
              "open": 16.92,
              "high": 17.1,
              "low": 16.74,
              "close": 16.81,
              "volume": 11512
          },
          {
              "time": "2015-02-11 23:00:00.000000",
              "open": 16.81,
              "high": 17.07,
              "low": 16.63,
              "close": 16.85,
              "volume": 14217
          },
          {
              "time": "2015-02-12 23:00:00.000000",
              "open": 16.86,
              "high": 17.45,
              "low": 16.85,
              "close": 17.35,
              "volume": 13400
          },
          {
              "time": "2015-02-15 23:00:00.000000",
              "open": 17.35,
              "high": 17.42,
              "low": 17.28,
              "close": 17.31,
              "volume": 5308
          },
          {
              "time": "2015-02-16 23:00:00.000000",
              "open": 17.29,
              "high": 17.34,
              "low": 16.3,
              "close": 16.53,
              "volume": 22112
          },
          {
              "time": "2015-02-17 23:00:00.000000",
              "open": 16.51,
              "high": 16.61,
              "low": 16.27,
              "close": 16.5,
              "volume": 16961
          },
          {
              "time": "2015-02-18 23:00:00.000000",
              "open": 16.51,
              "high": 16.8,
              "low": 16.36,
              "close": 16.39,
              "volume": 17057
          },
          {
              "time": "2015-02-19 23:00:00.000000",
              "open": 16.38,
              "high": 16.59,
              "low": 16.2,
              "close": 16.24,
              "volume": 14596
          },
          {
              "time": "2015-02-22 23:00:00.000000",
              "open": 16.27,
              "high": 16.62,
              "low": 16.1,
              "close": 16.33,
              "volume": 16215
          },
          {
              "time": "2015-02-23 23:00:00.000000",
              "open": 16.32,
              "high": 16.5,
              "low": 16.09,
              "close": 16.29,
              "volume": 17707
          },
          {
              "time": "2015-02-24 23:00:00.000000",
              "open": 16.28,
              "high": 16.74,
              "low": 16.28,
              "close": 16.57,
              "volume": 11301
          },
          {
              "time": "2015-02-25 23:00:00.000000",
              "open": 16.58,
              "high": 16.9,
              "low": 16.52,
              "close": 16.57,
              "volume": 9227
          },
          {
              "time": "2015-02-26 23:00:00.000000",
              "open": 16.58,
              "high": 16.7,
              "low": 16.42,
              "close": 16.59,
              "volume": 11486
          }
      ]
      

      My Cerebro class (Cerebros/OptimizerCerebro.py)

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      import backtrader as bt
      import datetime  # For datetime objects
      from DataFeeds.MyJSONFeed import MyJSONFeed
      
      
      class OptimizerCerebro(bt.Cerebro):
          options = {
              "fromdate": datetime.datetime(2010, 3, 1, 19, 0, 0),
              "todate": datetime.datetime(2020, 3, 1, 20, 0, 0),
              "endvalue": 0,
              "symbol": 'EUR_USD',
              "timeframe": bt.TimeFrame.Days,
              "compression": 1
          }
      
          def __init__(self, options):
              super().__init__()
              self.options.update(options)
      
          @property
          def run(self):
              # Create a cerebro entity
              cerebro = bt.Cerebro()
              startcash = 100000
      
              # Add a strategy
              if "strategy" not in self.options:
                  return False
      
              cerebro.optstrategy(self.options["strategy"], period=range(14, 21))
      
              # Create a Data Feed
              data = MyJSONFeed(
                  dataname='XAU_USD',
                  fromdate=self.options["fromdate"],
                  todate=self.options["todate"],
                  symbol=self.options["symbol"],
                  timeframe=self.options["timeframe"],
                  compression=1,
              )
      
              '''modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
              datapath = os.path.join(modpath, 'datas/orcl-1995-2014.txt')
      
              # Create a Data Feed
              data = bt.feeds.YahooFinanceCSVData(
                  dataname=datapath,
                  # Do not pass values before this date
                  fromdate=datetime.datetime(2000, 1, 1),
                  # Do not pass values after this date
                  todate=datetime.datetime(2000, 12, 31),
                  reverse=False)'''
      
              # Add the data to Cerebro
              cerebro.adddata(data)
      
              # Set our desired cash start
              cerebro.broker.setcash(startcash)
              cerebro.run()
      

      The strategy (Strategies/RSIBorderBounce.py)

      import backtrader as bt
      
      
      class RSIBorderBounce(bt.Strategy):
          params = (
              ('period', 21),
          )
      
          def log(self, txt, dt=None):
              """ Logging function for this strategy"""
              dt = dt or self.datas[0].datetime.datetime(0)
              print('%s, %s' % (dt, txt))
      
          def __init__(self):
              self.startcash = self.broker.getvalue()
              self.dataclose = self.datas[0].close
              self.rsi = bt.indicators.RSI_SMA(self.data.close, period=self.params.period, safediv=True)
      
          def next(self):
              if self.position:
                  print(self.position)
              if not self.position:
      
                  if self.rsi < 30:
                      self.log('buy, %.2f' % self.dataclose[0])
                      self.buy(size=1)
              else:
                  if self.rsi > 70:
                      self.log('sell, %.2f' % self.dataclose[0])
                      self.sell(size=1)
      
          def stop(self):
              pnl = round(self.broker.getvalue() - self.startcash, 2)
              print('RSI Period: {} Final PnL: {}'.format(
                  self.params.period, pnl))
      
      

      And my main script is

      import datetime  # For datetime objects
      import backtrader as bt
      
      from Cerebros.OptimizerCerebro import OptimizerCerebro
      from Strategies.RSIBorderBounce import RSIBorderBounce
      
      if __name__ == '__main__':
          testStrategy = OptimizerCerebro({
              "strategy": RSIBorderBounce,
              "fromdate": datetime.datetime(2015, 1, 1),
              "todate": datetime.datetime(2015, 3, 1),
              "endvalue": 0,
              "symbol": 'XAG_USD',
              "timeframe": bt.TimeFrame.Days,
              "compression": 1
          })
          testStrategy.run
      

      Can someone give me an advice?
      Thanks!

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