For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Why cerebro.broker.getvalue() is nan



  • Hi. I'm Japanese boy.
    I am trying a simple moving average strategy to grasp the behavior of backtrader.
    However, at the end of the test getvalue becomes nan.
    What's wrong?

    ・bt_data
    datetime stock_name high low close
    2018-08-14 S&P500 2843.1101 2826.5801 2839.9600
    2018-08-15 S&P500 2827.9500 2802.4900 2818.3701
    2018-08-16 S&P500 2850.4900 2831.4399 2840.6899
    2018-08-17 S&P500 2855.6299 2833.7300 2850.1299
    2018-08-20 S&P500 2859.7600 2850.6201 2857.0500


    #Strategy
    class Stg_MovingAgerage(bt.Strategy):
    
        params = (
            ('maperiod', 15), 
        )
        
        def __init__(self):
    
            self.dataclose = self.datas[0].close 
            self.order = None
            self.buyprice = None
            self.buycomm = None
        
            self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)
        
        
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                return
    
            if order.status in [order.Completed]:
                self.bar_executed = len(self)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                print('Order Canceled/Margin/Rejected')
    
            self.order = None
        
    
        def notify_trade(self, trade):
            """トレード収支"""
            if not trade.isclosed:
                return
    
            print(str(self.datas[0].datetime.date(0)) + ' OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm))
    
        
        
        def next(self):
            """トレード実行"""
    
            #print(str(self.datas[0].datetime.date(0)) + ' Close, %.2f' % self.dataclose[0] +  '  SMA, %.2f' % self.sma[0] )
            
            if self.order:
                return
    
            if not self.position:
                if self.dataclose[0] > self.sma[0]:
                    self.order = self.buy()
    
            else:
                if self.dataclose[0] < self.sma[0]:
                    self.order = self.sell()
        
        def stop(self):
            print('-------------------------')
            print('★RESULT★ Ending Value %.2f' %(self.broker.getvalue()))
    

    cerebro = bt.Cerebro()
    bt_data = bt.feeds.PandasData(dataname=df_input,datetime='datetime',close='close',openinterest=None)
    cerebro.adddata(bt_data)
    
    cerebro.broker.setcash(100000.0)
    cerebro.broker.setcommission(commission=0.001)
    cerebro.broker.getvalue()
    
    # Add a strategy
    cerebro.addstrategy(Stg_MovingAgerage)
    
    cerebro.run()
    
    cerebro.broker.getvalue()
    

    ★RESULT★ Ending Value nan


  • administrators

    You don't have opening prices, which makes all opening prices default to NaN, hence the resulting NaN



  • @backtrader

    Thank you for your reply.

    I corrected it and succeeded.

    bt_data = bt.feeds.PandasData(dataname=df_input,datetime='datetime',open='open',high='high',low='low',close='close',volume=None,openinterest=None)
    

    If the data source does not provide an indicator of open or high, only close,What should I do?
    Even if you did the following, it failed.

    bt_data = bt.feeds.PandasData(dataname=df_input,datetime='datetime',open=None,high=None,low=None,close='close',volume=None,openinterest=None)
    

  • administrators

    @atori said in Why cerebro.broker.getvalue() is nan:

    What should I do?

    Use some of the other prices to fill in the missing prices. But the broker needs OHLC to fulfill its tasks. If you don't use the broker, because you are only testing, for example, an indicator, you can use only the components you need.



  • I've done something similar once when I used backtrader to simulate betting.
    In your case you could try this:

    bt_data = bt.feeds.PandasData(dataname=df_input,datetime='datetime', open='close', high='close', low='close',close='close', volume=None, openinterest=None)
    

    However you should know that this ought to basically limit you to market orders, I wouldn't recommend using more complex order types with this as they'll likely behave in ways that are unique to your simulation ;)
    If you want to run "serious" simulations with backtrader, you really need to get yourself some OHCL data.

    Cheers



  • Thank you for your reply.
    I'll give it a try.And I will use OHCL data as much as possible.
    I am sorry for weird English.


  • administrators

    @atori said in Why cerebro.broker.getvalue() is nan:

    I am sorry for weird English.

    No need to apologize. I am sure everyone's Japanese is much worse than your English. Just keep on practicing (practice makes perfection ... or at least allows you to become better even if not perfect)