For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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 .

    (Figure_0.png

    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 error

      File "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 for self.datas[0] as well as self.data1 is a shortcut for self.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



});