Weird problem when passing data for specific stocks
I faced a weird issue when backtesting a basket of stocks today. I was testing the strategy in Nifty 50 basket from 2011 to 2021.
When I ran the strategy, I got annual returns with analyzer and it showed a weird O/P as in the image. The Annual returns was 0% for 2011 to 2017 for every year and then after 2018 the strategy gave returns.
After some manual work found out that HDFCLIFE and SBILIFE was listed on NSE only in 2017 and my strategy works post that only while rest of the 48 stocks are listed prior to 2011. When I ran the strategy without both stocks it gave returns for all years from 2011 to 2021.
Pls check the returns image when both stock were removed from list.
When 48 stocks are listed before the strategy start date and only 2 stocks are listed post that, data for all the stocks are tested only post the last listing date!!!
Why is it like that????
Nifty_50= ['ADANIPORTS','ASIANPAINT','AXISBANK','BAJAJ-AUTO','BAJAJFINSV','BAJFINANCE','BHARTIARTL','BPCL','BRITANNIA','CIPLA','COALINDIA','DIVISLAB','DRREDDY','EICHERMOT','GAIL','GRASIM','HCLTECH','HDFC','HDFCBANK','HDFCLIFE','HEROMOTOCO','HINDALCO','HINDUNILVR','ICICIBANK','INDUSINDBK','INFY','IOC','ITC','JSWSTEEL','KOTAKBANK','LT','M&M','MARUTI','NESTLEIND','NTPC','ONGC','POWERGRID','RELIANCE','SBILIFE','SBIN','SHREECEM','SUNPHARMA','TATAMOTORS','TATASTEEL','TCS','TECHM','TITAN','ULTRACEMCO','UPL','WIPRO'] if __name__ == "__main__": cerebro = bt.Cerebro() for i in Nifty_50: data = bt.feeds.InfluxDB( host='127.0.0.1', port='8086', username = 'admin', password = 'admin', database = 'tempdb', dataname = 'EOD_Data', Ticker = i, fromdate=dt.datetime(2011, 1, 1), todate=dt.datetime(2021, 3, 9), timeframe = bt.TimeFrame.Days, compression = 1, open='Open', high='High', low='Low', close='Close', volume='Volume', ointerest=None) cerebro.adddata(data, name=i) cerebro.addstrategy(Firststrategy) #cerebro.optstrategy(Firststrategy, malookback = [10,20,50,100,200], exitbars = range(3,11)) cerebro.addsizer(bt.sizers.PercentSizerInt, percents=10) cerebro.broker.setcommission(commission = 0.001) cerebro.broker.setcash(1000000.00) print('Starting Portfolio Value: %.1f' % cerebro.broker.getvalue()) cerebro = addAnalyzers(cerebro) cerebro = runcerebro(cerebro)
Even tried something like this, But didnt work
if __name__ == "__main__": cerebro = bt.Cerebro() for i in Nifty_50: if i != 'HDFCLIFE' or 'SBILIFE': start_date = dt.datetime(2011, 1, 1) else: start_date = dt.datetime(2018, 1, 1) data = bt.feeds.InfluxDB( host='127.0.0.1', port='8086', username = 'admin', password = 'admin', database = 'tempdb', dataname = 'EOD_Data', Ticker = i, fromdate=start_date, todate=dt.datetime(2021, 3, 9), timeframe = bt.TimeFrame.Days, compression = 1, open='Open', high='High', low='Low', close='Close', volume='Volume', ointerest=None) cerebro.adddata(data, name=i) cerebro.addstrategy(Firststrategy)
run-out last edited by
@spsandy715 Backtrader needs full lines for all data being put in. Backtrader will only start a strategy when all datas and indicators are ready to trade. It has no idea that you don't care about the two stocks prior to them being ready.
Just load them using pandas and fill the earlier dates with zeros. Then skip absent stocks in next with
for d in self.datas: if d.close == 0: continue
@run-out Thank you so much for the cue!!!!!
Though I didn't go for pandas, I added earlier dates with zero in influxdb itself and it worked perfectly!!!