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/

    How to do with self.broker.getvalue() which return NAN when do portfolio with different public date?

    General Code/Help
    1
    1
    69
    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.
    • A
      ArronTian last edited by

      when i run a portfolio strategy, the stocks have different public date, so I fill data with method ffill in python fillna, when i run the strategy, I find that i could not order buy or sell because when i get portfolio value by self.broker.getvalue which is NAN, i could not calculate the order size……help me, how to cope with it ?
      the error is :
      Traceback (most recent call last):
      File "Z:/QEPM_BackTest/src/dev/Backtest/single_factor_backtrade.py", line 360, in <module>
      run()
      File "Z:/QEPM_BackTest/src/dev/Backtest/single_factor_backtrade.py", line 345, in run
      thestrats = cerebro.run()
      File "D:\Anaconda\lib\site-packages\backtrader\cerebro.py", line 1127, in run
      runstrat = self.runstrategies(iterstrat)
      File "D:\Anaconda\lib\site-packages\backtrader\cerebro.py", line 1293, in runstrategies
      self._runonce(runstrats)
      File "D:\Anaconda\lib\site-packages\backtrader\cerebro.py", line 1695, in _runonce
      strat._oncepost(dt0)
      File "D:\Anaconda\lib\site-packages\backtrader\strategy.py", line 309, in _oncepost
      self.next()
      File "Z:/QEPM_BackTest/src/dev/Backtest/single_factor_backtrade.py", line 249, in next
      self.rebalance_portfolio()
      File "Z:/QEPM_BackTest/src/dev/Backtest/single_factor_backtrade.py", line 284, in rebalance_portfolio
      size = int(p_value / 100 / data.close[0]) * 100
      ValueError: cannot convert float NaN to integer

      the following is my code:
      class S_factors(bt.Strategy):
      params = dict(
      period=20,
      printlog=True, )

      def __init__(self):
          print("\n" + "*" * 30 + " Start trading " + "*" * 30)
          self.order = None
      
      def log(self, txt, dt=None, doprint=True):
          if self.params.printlog or doprint:
              dt = dt or self.datetime.date(0)
              print(f'{dt.isoformat()} {txt}')
      
      def notify_order(self, order):
          if order.status in [order.Submitted, order.Accepted]:
              return
          if order.status in [order.Completed]:
              if order.isbuy():
                  self.log(f'{self.broker.cash} {self.broker.getvalue()}')
              else:
                  sself.log(f'{self.broker.cash} {self.broker.getvalue()}')
          elif order.status in [order.Canceled]:
              self.log(f'{self.broker.cash} {self.broker.getvalue()}')
          elif order.status in [order.Margin]:
             self.log(f'{self.broker.cash} {self.broker.getvalue()}')
          elif order.status in [order.Rejected]:
              self.log(f'{self.broker.cash} {self.broker.getvalue()}')
          self.order = None
      
      def prenext(self):
          self.next() 
      
      def next(self):
         self.broker.getcash())
          if len(self.datas[0]) == self.data0.buflen():
              return
          if self.datas[0].is_resetday[0] == 1 \
                  and datetime.strptime(str(self.datetime.date(0)), "%Y-%m-%d") > datetime.strptime("2014-03-17", "%Y-%m-%d"):
              # print("resetday---->>>>>")
              self.rebalance_portfolio()
      
      def rebalance_portfolio(self):
          factor_vl = pd.Series()
          for data in self.datas:
              if not pd.isnull(data.close[0]) and data.industry[0] == self.p.selected_ind and not pd.isnull(data.factor[0]):
                  factor_vl[data._name] = data.factor[0]
          factor_vl.sort_values(ascending=False, inplace=True)
      
          layer_num = int(len(factor_vl) / self.p.layer_N)
          layer_num = max(layer_num, self.p.min_num_stk)
          long_list = [i for i in factor_vl.index[:layer_num]]
          for o in long_list:
              self.cancel(o)
          if len(long_list)==0:
              return
          total_value = self.broker.getvalue()
          p_value = total_value * 0.8 / layer_num
      
          self.datas.sort(key=lambda d: self.broker.getvalue([d]), reverse=True)
      
          for d in self.datas:
              print(data._name, self.broker.getvalue([d]))
      
          for data in self.datas:
              if data._name in long_list:
                  size = int(p_value / 100 / data.close[0]) * 100
                  # print(self.datetime.date(0), self.broker.getvalue(), self.broker.getcash())
                  # print("OHLC:", data.open[0], data.high[0], data.low[0], data.close[0])
                  self.order_target_size(data=data, target=size)
              else:
                  self.close(data=data, exectype=bt.Order.Close)
      
      1 Reply Last reply Reply Quote 0
      • 1 / 1
      • First post
        Last post
      Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors