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/

    Portfolio Run with as much data series as possible

    Indicators/Strategies/Analyzers
    3
    5
    180
    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.
    • B
      Bo last edited by

      Hi Community,

      I am backtesting a simple momentun strategy on a set of futures...however, these futures are listed on different start time. To be a bit more concrete, Assuming I have:

      Future1: from 2018 to 2021
      Future2: from 2019 to 2021
      Future3: from 2019 to 2020

      I would like to apply a simply momentun strategy on All three Futures. During 2018-2019, all initial cash value will be allocated to Future 1. During 2019-2020, available cash will be allocate equally to Future 1, 2 and 3. During 2020-2021, value will be allocate to Future1 and 2.

      I know I can run these futures separately and aggregate the results. However, this would be super cumbersome when it comes to aggregation and more importantly not very accurate since profit/loss could be rebalanced in portfolio run but not if I ran them seperately.

      But, to kick off portfolio run, I am facing a problem which is, based on backtrader, the actually backtesting would start only when Future2 is fully loaded, i.e. the first buy signal execution can only happen after 2019. And I am also not sure what is going to happen after 2020 since Future3 no longer exsits.

      I have tried to load the data by specifying fromdate and todate like follow:

      *data1=data.iloc[-100:,:]
      data1.index=data1.DATETIME

      data2=data.iloc[-50:,:]
      data2.index=data2.DATETIME

      cerebro = bt.Cerebro() # create a "Cerebro" engine instance
      datax1=bt.feeds.PandasData(dataname=data1,fromdate=min(data1.DATETIME),todate=min(data1.DATETIME),timeframe=bt.TimeFrame.Days)
      datax2=bt.feeds.PandasData(dataname=data2,fromdate=min(data2.DATETIME),todate=min(data2.DATETIME),timeframe=bt.TimeFrame.Days)

      cerebro.broker.setcash(1000.0)
      cerebro.broker.set_slippage_perc(0.0001)
      cerebro.broker.setcommission(commission=0.0001)
      cerebro.adddata(datax1) # Add the data feed
      cerebro.adddata(datax2) # Add the data feed
      cerebro.addstrategy(Naive_Momentun_Print) # Add the trading strategy
      cerebro.broker.addcommissioninfo(CommInfoFractional())
      cerebro.run()*

      But it gives me this error:
      File "/lib/python3.7/site-packages/backtrader/linebuffer.py", line 672, in once
      dst[i] = src[i + ago]

      IndexError: array assignment index out of range

      I am not sure what to try out next. Hope someone in the community can help out.

      Thanks in Advance!
      Bo

      ####################################
      #Attached below is my native stategy:
      ####################################
      class Naive_Momentun_Print(bt.Strategy):
      # list of parameters which are configurable for the strategy
      params = (
      # Standard Parameters
      ('period', 25),
      )

      def __init__(self):
          self.mom = [bt.indicators.MomentumOscillator(i, period=self.params.period) for i in self.datas]
          
          
      def notify_order(self, order):
          if order.status in [order.Completed]:
              if order.isbuy():
                  self.log('Buy Order EXECUTED, %.2f, SIZE of: %.2f, Asset of: %s' % (order.executed.price,order.executed.size,order.info))
              if order.issell():
                  self.log('Sell Order EXECUTED, %.2f, SIZE of: %.2f, Asset of: %s' % (order.executed.price,order.executed.size,order.info))
      
      
      def notify_trade(self, trade):
          if not trade.isclosed:
              return
          self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                   (trade.pnl, trade.pnlcomm))
      
      def start(self):    
          self.order = None  # sentinel to avoid operrations on pending order
      
      def next(self):
          print (""""Time: {0}""".format(self.datas[0].datetime.datetime(0)))
          
          c = [i.momosc[0] for i in self.mom]
          
          for i in range(0,len(c)):
                 if self.broker.getposition(data=self.datas[i]).size==0:
                     self.order_target_percent(data=self.datas[i], target=0.49)
                 else:
                     self.order_target_percent(data=self.datas[i], target=0)
      
      def log(self, txt, dt=None):
          dt = dt or self.datas[0].datetime.datetime(0)
          print('%s, %s' % (dt.isoformat(), txt))
      
      1 Reply Last reply Reply Quote 0
      • run-out
        run-out last edited by

        @bo This answer gives a rough idea of how to approach it. Create an index covering the entire period. Use pandas to reindex your data for the whole period using 0 value when the future is not trading. Load into backtrader using pandas feed.

        Then filter out 0 datas in your next

        RunBacktest.com

        B 2 Replies Last reply Reply Quote 0
        • B
          Bo @run-out last edited by

          @run-out IT WORKS!
          Thank you for your swift prompt. My struggling was having passed unaligned datetime index. Once the index are the same, I can do all kinds of filtering and calculation.
          Thanks again!

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

            @run-out Hi

            I am running into another issue using your method. If I algined datatime, then when I calculate indicators like MACD, the futures that issued later in time will all be NAN. I won't be able to leverage powerful indicator functions build in Backtrader.

            If I filled all nan close price to 0, then I won't be able to calculate MACD currectly in the first data points.

            Is there any other elegate solutions? such as specify min_period or have indicator calucation ignoring nan?

            vladisld 1 Reply Last reply Reply Quote 0
            • vladisld
              vladisld @Bo last edited by

              @bo Another option is to utilize the prenext method. See the example here:
              https://www.backtrader.com/blog/2019-05-20-momentum-strategy/momentum-strategy/#next-and-prenext

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