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/

    Adding custom indicator

    Indicators/Strategies/Analyzers
    2
    3
    2684
    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.
    • M
      maxpaton last edited by maxpaton

      I have developed my first custom backtrader indicator class (in a separate file) which calculates resistance values. The first thing I do in the next() method of this indicator class is to get the previous 8 values of self.data and store them in an array named 'ltp', like so:

      class supres(bt.Indicator):
      
          lines = ('support','resistance')
          params = (('n', 8),)
          
          def __init__(self):
      
              #converting n to a nearest even number
              if self.p.n%2 != 0:
                  self.p.n += 1
      
          def next(self):
      
              ltp = self.data.get(ago=0, size=self.p.n)
              print(ltp)
      

      When I come to call the indicator in the init of my strategy, I pass in self.data[0]. But the self.data[0] doesn't seem to be available in the the indicator class. When I print out 'ltp' from the indicator class the array is empty.

      Here is my strategy code for the init and main that isolates the problem:

      import backtrader as bt
      import datetime
      from backtrader import indicators as ind
      import numpy as np
      
      from supres_ind import supres
      
      # Create strategy
      class TestStrategy(bt.Strategy):
              
          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose = self.datas[0].close
              
              #calls the indicator
              self.support = supres(self.datas[0])
      

      and

      if __name__ == '__main__':
          
          datapath = '../../data/raw_bitcoin_data_copy.csv'
          data = bt.feeds.BacktraderCSVData(
              dataname=datapath,
              fromdate=datetime.datetime(2017, 1, 1),
              todate=datetime.datetime(2017, 7, 1),
              adjclose=False)
          
          cerebro = bt.Cerebro()
          cerebro.adddata(data)
          cerebro.addstrategy(TestStrategy)
          
          cerebro.broker.setcash(100000.0)
          cerebro.addsizer(bt.sizers.SizerFix, stake=10)
          cerebro.broker.setcommission(0.001) #0.1%
          print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
          cerebro.run()
          print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      

      Do I have to add the indicator class to the cerebro engine somehow? And does the indicator have to be called with bt.ind prefix?

      Here is the form of the data:

      timestamp	open	high	low	close	volume	adj close
      2017-01-01	973.37	1000	964.37	992.95	4421.502883	992.95
      2017-01-02	992.96	1034.39	990.52	1011.45	7723.635752	1011.45
      2017-01-03	1011.52	1036.99	1006.71	1020.67	8614.250058	1020.67
      2017-01-04	1020.69	1147	1018	1130.3	16222.23027	1130.3
      2017-01-05	1131.1	1175	880	1007	20438.58193	1007
      2017-01-06	1007	1033.85	875.01	895.71	14262.50427	895.71
      

      Cheers

      B 1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators @maxpaton last edited by

        @maxpaton said in Adding custom indicator:

        When I come to call the indicator in the init of my strategy, I pass in self.data[0]. But the self.data[0] doesn't seem to be available in the the indicator class. When I print out 'ltp' from the indicator class the array is empty.

        There is nothing telling the framework how many bars make up the lookback period. Neither you nor additional elements in your indicator (like a Moving Average) what the period will be. It cannot as such provide you with n bars of information in advance.

        Subclass your indicator from: PeriodN which already provides a period parameter and will do it for you.

        M 1 Reply Last reply Reply Quote 0
        • M
          maxpaton @backtrader last edited by

          @backtrader Got it now, thanks

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