For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
MultiData Strategy excludes older data points from different feeds
-
I am trying to include fundamental data for along with ohlc for single ticker as data feed. I add multiple datafeeds and try to run cerebro for validation. But i can see the data used for backtesting shows data only when all the data feeds are available.
Is this expected behavior ?try: del cerebro except NameError: pass cerebro = bt.Cerebro() selected_daily_columns = ['open', 'high', 'low', 'close', 'volume'] selected_fundamental_columns = ["debt","cashneq","equity","de"] custom_params = [('datetime', "date"), ('openinterest',None)] custom_params += [(name, name) for name in selected_daily_columns] custom_params += [(name, name) for name in selected_fundamental_columns] class PandasCustomData(bt.feeds.PandasData): lines = tuple(selected_fundamental_columns) params = tuple(custom_params) ticker_data_feed = ['LCTX', 'PTN', 'XXII', 'CSLT'] ticker_data_feedi = {k: v for v, k in enumerate(ticker_data_feed)} for ticker in ticker_data_feed: data_sep_ = data_sep[data_sep.ticker == ticker] data_sf1_ = data_sf1[data_sf1.ticker == ticker] df_ = data_sep_.merge(data_sf1_.rename({"datekey":"date"}, axis=1), on=["ticker","date"], how="left").sort_values(by="date") print(f"{ticker} min_date:{df_.date.min()}") pd_data_feed = PandasCustomData(dataname=df_, name=ticker) del df_, data_sep_, data_sf1_ gc.collect() cerebro.adddata(pd_data_feed) class TestStrategy(bt.Strategy): def log(self, txt, dt=None): ''' Logging function for this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries pass def next(self): # Simply log the closing price of the series from the reference msg = "" for ticker,tickeri in ticker_data_feedi.items(): msg += f' ;{ticker} Close:{self.datas[tickeri].close[0]:.2f}' msg += "" if pd.isna(self.datas[tickeri].equity[0]) else f' Equity:{self.datas[tickeri].equity[0]}' msg += "" if pd.isna(self.datas[tickeri].de[0]) else f' DE:{self.datas[tickeri].de[0]}' self.log( msg ) # Add a strategy cerebro.addstrategy(TestStrategy) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=20) # Set our desired cash start cerebro.broker.setcash(10000.0) # Set the commission - 0.1% ... divide by 100 to remove the % cerebro.broker.setcommission(commission=0.001) # Print out the starting conditions print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) # Run over everything cerebro.run(oldsync=False) # Print out the final result print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
The output shows starts as
LCTX min_date:1997-12-31 00:00:00 PTN min_date:1997-12-31 00:00:00 XXII min_date:2011-01-26 00:00:00 CSLT min_date:2014-03-14 00:00:00 Starting Portfolio Value: 10000.00 2014-03-14, ;LCTX Close:3.71 ;PTN Close:1.04 ;XXII Close:4.60 ;CSLT Close:39.80 2014-03-17, ;LCTX Close:3.57 Equity:14800768.0 DE:1.045 ;PTN Close:1.08 ;XXII Close:4.44 ;CSLT Close:37.25 2014-03-18, ;LCTX Close:3.45 ;PTN Close:1.09 ;XXII Close:4.35 ;CSLT Close:33.65 2014-03-19, ;LCTX Close:3.38 ;PTN Close:1.26 ;XXII Close:3.79 ;CSLT Close:31.50 2014-03-20, ;LCTX Close:3.51 ;PTN Close:1.23 ;XXII Close:3.98 ;CSLT Close:31.99 2014-03-21, ;LCTX Close:3.52 ;PTN Close:1.44 ;XXII Close:3.53 ;CSLT Close:29.35 2014-03-24, ;LCTX Close:3.36 ;PTN Close:1.29 ;XXII Close:2.69 ;CSLT Close:27.33 2014-03-25, ;LCTX Close:3.37 ;PTN Close:1.30 ;XXII Close:3.22 ;CSLT Close:25.90 2014-03-26, ;LCTX Close:3.26 ;PTN Close:1.20 ;XXII Close:3.16 ;CSLT Close:24.77 2014-03-27, ;LCTX Close:3.24 ;PTN Close:1.18 ;XXII Close:3.13 ;CSLT Close:23.46 ....
-
Yes, this is expected default behavior. To use all history you need to use both
prenext()
andnext()
calls. This was discussed on the forum several times, search for it.