Portfolio Run with as much data series as possible
-
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 2020I 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.DATETIMEdata2=data.iloc[-50:,:]
data2.index=data2.DATETIMEcerebro = 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))
-
-
@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! -
@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?
-
@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