unable to execute strategies on resampled data
-
Hi Traders ,
I needed assistance with an issue i was facing.Here is my code :
# This is the Implementation for 9/30 Stratergy using python BackTrader import backtrader as bt from datetime import datetime import datetime as dt import pandas as pd import matplotlib.pyplot as plt from pandas_datareader import data as web class PullBack(bt.Strategy): def log(self, txt, dt=None): # Logging function fot this strategy dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.open = self.data.open self.high = self.data.high self.low = self.data.low self.close = self.data.close self.ema = bt.ind.ExponentialMovingAverage(self.data.close, period=9) self.wma = bt.ind.WeightedMovingAverage(self.data.close, period=30) self.order = None self.stop_order = None def next(self): #print("current portfolio value" + str(cerebro.broker.getvalue())) if not self.position: # Long Position if (self.ema[-1] > self.wma[-1]) and (self.data.high[-1] < self.ema[-1]) : self.buy(size=100, exectype=bt.Order.StopLimit, price=self.data.high[-1]) self.order = self.buy(size=1, exectype=bt.Order.Limit, price=self.data.high[-1]) self.log('BUY PRICE CREATED , %.2f ' % self.data.high[-1]) risk = (self.data.high[-1] - self.data.low[-1]) self.log('Risk points , %.2f' % risk) # Place a stop loss order self.sell(size=100, exectype=bt.Order.StopLimit, price=self.data.low[-1]) target_price = self.data.high[-1] + 2 * (self.data.high[-1] - self.data.low[-1]) self.log('TARGET PRICE ,%.2f ' % target_price) oc1 = self.sell(size=1, exectype=bt.Order.StopLimit, price=target_price) self.order = self.sell(size=1, exectype=bt.Order.Stop, price=self.data.low[-1], plimit=self.data.low[-1] , oco=oc1) # elif (self.ema[-1] < self.wma[-1]) and (self.data.close[-1] > self.ema[-1] ) : # self.order = self.sell(size=1,exectype=bt.Order.Limit,price=self.data.low[-1]) # #Stop loss # target_price = self.data.low[-1] - 2 * (self.data.high[-1] - self.data.low[-1]) # self.order = self.sell(size=1,exectype=bt.Order.StopLimit,price=target_price) # self.log('Short Sell initiated , %.2f' % self.data.low[-1]) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log('BUY EXECUTED, %.2f' % order.executed.price) elif order.issell(): self.log('Sell order EXECUTED, %.2f' % order.executed.price) elif order.status in [order.Cancelled]: self.log('Order Canceled at price, %.2f' %order.price) elif order.status in [ order.Margin, order.Rejected]: self.log('Order Rejected or Margin error') self.order = None class timeAdjustment(bt.TradingCalendar): params = dict( holidays=[ dt.date(2018, 1, 26), # dt.date(2018, 2, 13), # dt.date(2018, 3, 2), # dt.date(2018, 3, 29), # dt.date(2018, 3, 30), # dt.date(2018, 5, 1), # dt.date(2018, 8, 15), # dt.date(2018, 8, 22), # dt.date(2018, 9, 13), # dt.date(2018, 9, 18), # dt.date(2018,10,2), # dt.date(2018,10,18), # dt.date(2018,11,8), # dt.date(2018,11,23), # dt.date(2018,12,2) ], # earlydays=[ # (dt.date(2018, 11, 7), # dt.time(17, 31), dt.time(18, 31)) # ], open=dt.time(9, 16), close=dt.time(15, 30), ) #Variable for our starting cash startcash = 100000 #Create an instance of cerebro cerebro = bt.Cerebro() #Add our strategy cerebro.addstrategy(PullBack) nifty_futures="C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\BackTestFiles\\input_data\\BANKNIFTY-IBKR (1).csv" # nifty_futures = 'C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\2018data.csv' data = bt.feeds.GenericCSVData( headers=True, dataname=nifty_futures, # 2020-03-13 fromdate=datetime(2018, 1, 1), #year-month-date todate=datetime(2018, 1, 31), nullvalue=0.0, dtformat=("%Y-%m-%d %H:%M:%S"), # tmformat=('%H:%M:%S'), datetime=1, # time=3, open=2, high=3, low=4, close=5, timeframe=bt.TimeFrame.Minutes, plot=False ) cerebro.adddata(data) cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=30,name='30_Min_data') # cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=60,name='60_min_bar') # cerebro.addcalendar(timeAdjustment) # Set our desired cash start cerebro.broker.setcash(startcash) # Add the analyzers we are interested in cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta") cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn") cerebro.broker.setcommission(commission=0.0005) # Run over everything strategies=cerebro.run() #Get final portfolio Value portvalue = cerebro.broker.getvalue() print("final and last port value: "+str(portvalue)) pnl = portvalue - startcash #Print out the final result print('Final Portfolio Value: ${}'.format(portvalue)) print('P/L: ${}'.format(pnl)) #Finally plot the end results cerebro.plot(style='candlestick',fmt_x_data = ('%Y-%m-%d %H:%M:%S'))
Ideally I want my strategy to run on resampled data , but in the end what i get is the below plot .
(
As you can see no Buy sell indiactors have been displayed.
May i know why this happening ??I also tried commenting
cerebro.add(data)But this change gives me an empty plot .
Thanks
-
You need to use resampled data in your strategy which is data1, but you are referencing the data aka data0 which is the input data.
-
Thanks for the input rajan
-
I made the changes you mentioned ie reference data by data[1]
. I tried using data1 but it gave me an error saying it was undefined.
However after using data[1] I got this errorFile "c:\Nikhil_Media\Education & Skills\Stratergies_Codes\BackTestFiles\Resampled_930Stratergy.py", line 18, in __init__ self.open = self.data[1].open AttributeError: 'float' object has no attribute 'open'
Below is the modified code
Appreciate your assistance# This is the Implementation for 9/30 Stratergy using python BackTrader import backtrader as bt from datetime import datetime import datetime as dt import pandas as pd import matplotlib.pyplot as plt from pandas_datareader import data as web class PullBack(bt.Strategy): def log(self, txt, dt=None): # Logging function fot this strategy dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.open = self.data[1].open self.high = self.data[1].high self.low = self.data[1].low self.close = self.data[1].close self.ema = bt.ind.ExponentialMovingAverage(self.data[1].close, period=9) self.wma = bt.ind.WeightedMovingAverage(self.data[1].close, period=30) self.order = None self.stop_order = None def next(self): #print("current portfolio value" + str(cerebro.broker.getvalue())) if not self.position: # Long Position if (self.ema[-1] > self.wma[-1]) and (self.data[1].close[-1] < self.ema[-1]) : print('close price : {}, ema : {}'.format(self.data[1].close[-1],self.ema[-1])) print('current close price {}'.format(self.data[1].high[0])) # self.buy(size=100, exectype=bt.Order.StopLimit, price=self.data.high[-1]) self.order = self.buy(size=1, exectype=bt.Order.Limit, price=self.data[1].high[-1]) self.log('BUY PRICE CREATED , %.2f ' % self.data[1].high[-1]) risk = (self.data[1].high[-1] - self.data[1].low[-1]) self.log('Risk points , %.2f' % risk) # Place a stop loss order # self.sell(size=100, exectype=bt.Order.StopLimit, price=self.data.low[-1]) target_price = self.data[1].high[-1] + 2 * (self.data[1].high[-1] - self.data[1].low[-1]) self.log('TARGET PRICE ,%.2f ' % target_price) oc1 = self.sell(size=1, exectype=bt.Order.StopLimit, price=target_price) self.order = self.sell(size=1, exectype=bt.Order.Stop, price=self.data[1].low[-1], plimit=self.data[1].low[-1] , oco=oc1) # elif (self.ema[-1] < self.wma[-1]) and (self.data.close[-1] > self.ema[-1] ) : # self.order = self.sell(size=1,exectype=bt.Order.Limit,price=self.data.low[-1]) # #Stop loss # target_price = self.data.low[-1] - 2 * (self.data.high[-1] - self.data.low[-1]) # self.order = self.buy(size=1,exectype=bt.Order.StopLimit,price=target_price) # self.log('Short Sell initiated , %.2f' % self.data.low[-1]) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log('BUY EXECUTED, %.2f' % order.executed.price) elif order.issell(): self.log('Sell order EXECUTED, %.2f' % order.executed.price) elif order.status in [order.Cancelled]: self.log('Order Canceled at price, %.2f' %order.price) elif order.status in [ order.Margin, order.Rejected]: self.log('Order Rejected or Margin error') self.order = None class timeAdjustment(bt.TradingCalendar): params = dict( holidays=[ dt.date(2018, 1, 26), # dt.date(2018, 2, 13), # dt.date(2018, 3, 2), # dt.date(2018, 3, 29), # dt.date(2018, 3, 30), # dt.date(2018, 5, 1), # dt.date(2018, 8, 15), # dt.date(2018, 8, 22), # dt.date(2018, 9, 13), # dt.date(2018, 9, 18), # dt.date(2018,10,2), # dt.date(2018,10,18), # dt.date(2018,11,8), # dt.date(2018,11,23), # dt.date(2018,12,2) ], # earlydays=[ # (dt.date(2018, 11, 7), # dt.time(17, 31), dt.time(18, 31)) # ], open=dt.time(9, 16), close=dt.time(15, 30), ) #Variable for our starting cash startcash = 100000 #Create an instance of cerebro cerebro = bt.Cerebro() #Add our strategy cerebro.addstrategy(PullBack) nifty_futures="C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\BackTestFiles\\input_data\\BankNifty30min.csv" # nifty_futures = 'C:\\Nikhil_Media\\Education & Skills\\Stratergies_Codes\\2018data.csv' # Note : For custom created csv's ( like resampled ones ) always mention which columns are not present in the # data feed data = bt.feeds.GenericCSVData( headers=True, dataname=nifty_futures, # 2020-03-13 fromdate=datetime(2019, 1, 1), #year-month-date todate=datetime(2019, 1, 31), nullvalue=0.0, dtformat=("%Y-%m-%d %H:%M:%S"), # tmformat=('%H:%M:%S'), datetime=0, # time=3, open=1, high=2, low=3, close=4, volume = -1, openinterest = -1, timeframe=bt.TimeFrame.Minutes, # plot=False ) cerebro.adddata(data) # cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=30,name='30_Min_data') # cerebro.resampledata(data,timeframe=bt.TimeFrame.Minutes,compression=60,name='60_min_bar') # cerebro.addcalendar(timeAdjustment) # Set our desired cash start cerebro.broker.setcash(startcash) # Add the analyzers we are interested in cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta") cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn") cerebro.broker.setcommission(commission=0.0005) # Run over everything strategies=cerebro.run() #Get final portfolio Value portvalue = cerebro.broker.getvalue() print("final and last port value: "+str(portvalue)) pnl = portvalue - startcash #Print out the final result print('Final Portfolio Value: ${}'.format(portvalue)) print('P/L: ${}'.format(pnl)) #Finally plot the end results cerebro.plot(style='candlestick',fmt_x_data = ('%Y-%m-%d %H:%M:%S'))
-
@Nikhil-Kumar
you should first read Platform concepts and handling MultiTimeframe in backtrader. It will save lots of time for you. That would have clarified that datas[0] is not data0. You need to use data1 rather than data[1]. -
@rajanprabu said in unable to execute strategies on resampled data:
That would have clarified that datas[0] is not data0. You need to use data1 rather than data[1].
self.data0
is a shortcut forself.datas[0]
as well asself.data1
is a shortcut forself.datas[1]
.@Nikhil-Kumar said in unable to execute strategies on resampled data:
I made the changes you mentioned ie reference data by data[1]
you commented out resampling of the data, therefore the script has no
data1
. -
@ab_trader Thank you.. perhaps its me who has to read the docs again.
-
Thanks @rajanprabu and @ab_trader for your assistance and knowledge .
Appreciate it