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/

    Volume in multidata

    General Code/Help
    2
    5
    74
    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.
    • G
      gten last edited by

      Hi All,

      I am facing issue to access for multi-data, please refer the code below:

          params = dict(
              selcperc=0.10,  # percentage of stocks to select from the universe
              rperiod=1,  # period for the returns calculation, default 1 period
              vperiod=36,  # lookback period for volatility - default 36 periods
              mperiod=12,  # lookback period for momentum - default 12 periods
              reserve=5,  # 5% reserve capital
          )
          
          def log(self, arg):
                  print('{} {}'.format(self.datetime.date(), arg))   
                  
          def __init__(self):
              # calculate 1st the amount of stocks that will be selected
              self.selnum = int(len(self.datas) * self.p.selcperc)
              print(int(len(self.datas) * self.p.selcperc))
              # allocation perc per stock
              # reserve kept to make sure orders are not rejected due to
              # margin. Prices are calculated when known (close), but orders can only
              # be executed next day (opening price). Price can gap upwards
              self.perctarget = (100 - self.p.reserve) / self.selnum
              print((100 - self.p.reserve) / self.selnum)
              # returns, volatilities and momentums
              rs = [bt.ind.PctChange(d, period=self.p.rperiod) for d in self.datas]
              vs = [bt.ind.StdDev(ret, period=self.p.vperiod) for ret in rs]
              ms = [bt.ind.ROC(d, period=self.p.mperiod) for d in self.datas]
              volume = [bt.indicators.MovingAverageSimple(d, period = 2) for d in self.datas[0].volume]
              
              # simple rank formula: (momentum * net payout) / volatility
              # the highest ranked: low vol, large momentum, large payout
              # self.ranks = {d: d.npy * m / v for d, v, m in zip(self.datas, vs, ms)}
              self.ranks = {d: bt.DivByZero(m, v) for d, v, m, volu in zip(self.datas, vs, ms, volume) if volu > 100000}
      
      

      Above is giving error:

          self.ranks = {d: bt.DivByZero(m, v) for d, v, m, volu in zip(self.datas, vs, ms, volume) if volu > 100000}
      TypeError: __bool__ should return bool, returned LineOwnOperation
      

      I am not an expert, any pointers to fix the issue?

      1 Reply Last reply Reply Quote 1
      • run-out
        run-out last edited by

        volu refers to volume which is I think list comprehenion of SMA indicator objects. You won't be able to compare each value with a scalar.

        1 Reply Last reply Reply Quote 0
        • G
          gten last edited by

          thanks @run-out , is there any other way? I am trying to filter out stocks whose average volume is greater than certain value.

          run-out 1 Reply Last reply Reply Quote 0
          • run-out
            run-out @gten last edited by

            @gten Yes, you create an dictionary to keep track of your indicators for each datas you have put into the backtest.

            Then in init you loop through the datas to create your indicator. If you use > you will have a line of binary 1 or 0. You can then call these values at each 'next' to determine the truth value an any bar of your data volume being greater than the threshold. Here is the sample code:

            import backtrader as bt
            import yfinance as yf
            
            class Strategy(bt.Strategy):
            
                def log(self, txt, dt=None):
                    """ Logging function fot this strategy"""
                    dt = dt or self.data.datetime[0]
                    if isinstance(dt, float):
                        dt = bt.num2date(dt)
                    print("%s, %s" % (dt, txt))
            
                def __init__(self):
                    self.sma_dict = {}
                    self.p.volume_threshold = 15000000
            
                    # Average volume over threshold
                    for d in self.datas:
                        self.sma_dict[d] = bt.ind.SMA(d.volume, period=30) > self.p.volume_threshold
            
                def next(self):
                    for d in self.datas:
                        self.log(f"{d._name},\tvolume: {int(d.volume[0]):10,d},\tave_volume_gt: {int(self.sma_dict[d][0]):2d}")
                    print("\n")
                    return
            
            
            def runstrategy():
            
                cerebro = bt.Cerebro()
            
                fromdate = "2020-01-15"
                todate = "2020-06-19"
            
                interval = "1d"
            
                data0 = bt.feeds.PandasData(
                    dataname=yf.download(
                        "AAPL", start=fromdate, stop=todate, interval=interval
                    ),
                    name="AAPL",
                )
                cerebro.adddata(data0)
            
                data1 = bt.feeds.PandasData(
                    dataname=yf.download(
                        "MSFT", start=fromdate, stop=todate, interval=interval
                    ),
                    name="MSFT",
                )
                cerebro.adddata(data1)
            
                data2 = bt.feeds.PandasData(
                    dataname=yf.download(
                        "TSLA", start=fromdate, stop=todate, interval=interval
                    ),
                    name="TSLA",
                )
                cerebro.adddata(data2)
            
                cerebro.addstrategy(Strategy)
            
                cerebro.run()
            
            
            if __name__ == "__main__":
                runstrategy()
            
            
            G 1 Reply Last reply Reply Quote 0
            • G
              gten @run-out last edited by

              Thank you @run-out, makes sense.

              1 Reply Last reply Reply Quote 1
              • 1 / 1
              • First post
                Last post
              Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
              $(document).ready(function () { app.coldLoad(); }); }